Gatsby createPage() Slug Not Consistent from Local to Live Environment

Site Name: nervous-elion-083963
Framework: Gatsby
CMS: Dato

I have a bit of an odd situation going on with the Events page of my Gatsby site that I’m hoping someone might be able to provide some insight on. There’s a bit of nuance to this, so I’ll try to be as thorough as possible while hopefully keeping it brief as well.

For the Events portion of our website, when an Event is added to Dato a slug is generated automatically from the title (e.g. “Go Discover” becomes “go-discover”). In addition to that I take the start date of the Event—which is entered using Dato’s DateTime input—and generate a formatted string that is appended to the primary slug to help ensure there are no collisions with similarly named Events (e.g. if we have a “Go Discover” Event on July 1st and a “Go Discover” Event on August 1st, the full slugs generated would be “go-discover-2020-07-01” and “go-discover-2020-08-01” respectively).

This is all handled in my gatsby-node.js file when using the createPage() function (the following screenshot is of a few relevant portions of that file showing what is going on):

You can see from the screenshots above that I’m using GraphQL to bring in the Event and also its start date and using formatString() to convert it to a timestamp. I then have a wrapper function for createPage() called hccCreatePages(), which you can see in the final screenshot. In that final screenshot, you can see that I’m using Moment.js to generate the YYYY-MM-DD date slug, which is appended to the main slug. That complete slug is then passed in to create the page’s final destination.

This whole setup has worked great so far on our Events page. However, just recently we noticed that a select few Events on that page are not going to the proper destination. After looking into it, I realized that this date slug at the end is not always getting generated properly. For example, take the “Red Sea Rules Women’s Study” Event on July 16th, 2020 on our Events page. This Event should go to, but going to that destination directly from the listing on the page results in a 404. However, for some reason the page is instead getting generated with a date slug using the next day at

Notice how the date portion of the slug for when the page got created is incorrect…although all other information on the page is correct. One odd thing about all of this is that it is NOT an issue on my local install. The date portion of the slug is generated correctly, and the proper destination page is working as it should:

Even stranger still, as I mentioned previously this is only happening for a select few events. The vast majority of events are getting generated with the correct YYYY-MM-DD slug.

Is there some nuance with using Moment.js to generate these strings that I’m missing that could be causing the issue? Everything is working as it should on my local install, so I don’t know if there’s something I need to configure in Netlify or Gatsby that sets timezone information perhaps? Maybe that has something to do with these select few slugs being off.

Any help would be greatly appreciated to help point me in the right direction. Thanks!

What a mystery! Checking our logs, I can see that /red-sea-rules-women-study-2020-07-16/index.html was never uploaded as part of your deploy, but /red-sea-rules-women-study-2020-07-17/index.html was.

In the last screenshot, what was the original event.start that you then used Moment to format? Also, what’s that extra ‘x’ argument within the moment() call?

In the meantime, maybe Dato’s forum also something useful on how DateTime works (though looks like UTC to me at a glance):

Howdy, @jen!

Thanks for jumping in and taking the time to look through things! I was finally able to track down the culprit. :slight_smile:

This was my first project doing anything with timezones and datetime manipulation from scratch, so I was performing a few actions that were throwing things off. Namely, I was using formatString('x') on my GraphQL calls for anything time related to convert it to a timestamp. The thought was that this would give me a uniform piece of data to work with everywhere on the frontend since some of my inputs from Dato are using datetime, while others are simple date inputs. However, I didn’t realize it was stripping out the UTC offset from the datetime input for our events to help give me the local time.

Since the timezone information was missing due to the formatString() conversion, every event’s start and end time were being output as 00:00 UTC. We are located in Texas, which is -05:00 UTC, so any event with a start time of 7:00pm or later was considered to be happening on the day after. This is why /red-sea-rules-women-study-2020-07-17/index.html was output as part of the deploy instead of /red-sea-rules-women-study-2020-07-16/index.html, as its start time was 7:15pm.

To rectify this, I just abandoned using formatString() altogether and and updated my helper functions to look out for the incoming format from the datetime inputs (YYYY-MM-DDTHH:mm:ss-Z) and date inputs (YYYY-MM-DD) and treat them accordingly. Definitely a mistake on my part…but a good learning experience, haha.

As for your question regarding the extra 'x' argument in the moment() call, that is an optional parameter that can be used if you know the format of the input string. So if your input is '2020-07-03', you could pass in 'YYYY-MM-DD' to clarify the order. Since I was previously converting everything to a timestamp, I just passed in 'x' to clarify that the timestamp was being used. Using the formats mentioned above is what I’m doing moving forward and everything seems to be working as expected.

Thanks again for taking the time to check in on the thread and hopefully somebody else can learn from my mistakes in the future if they run into a similar situation! :laughing:

1 Like

thanks so much for sharing that explanation! makes sense!