First Impressions of Gatsby

Important Takeaways for Anyone Starting with Gatsby

Gatsby Monogram / Courtesy of gatsbyjs.org

Jesse Pledger, Senior Engineer

Jan. 28, 2020

Future Foundry rebranded recently and as part of that process designed a new marketing website. We initially planned to build the website using Create React App, having prior experience with it, but noticed a footnote in its documentation  -

“If your website is mostly static (for example, a portfolio or a blog), consider using Gatsby instead”

Our website was mostly static, and we were immediately impressed with the speed and simplicity that Gatsby promised. Additionally, ease of hosting using services such as Netlify and extensibility with a multitude of CMS’s. Intrigued, we decided to take the jump. In this article, we’d like to highlight a few takeaways from our experiences regarding differences from normal workflows, gotchas, and general wisdom that might help others starting out with Gatsby.

Our Takeaways


1. You won’t always have the DOM


If you’re used to working with SSR you might be familiar with this, but when working with Gatsby you won’t always have access to objects such as window, localStorage, document, sessionStorage, and navigator. To address this, be sure code accessing those variables are either wrapped in conditional checks or leverage the useEffect React Hook or componentDidMount React lifecycle method.

If you use Loadable Components (and you should be doing some sort of code splitting), these can also address issues with browser globals being unavailable. We have found this especially useful when using D3 animations. 

As a side note, we use D3 at Future Foundry for animation-intensive portions of our apps. Initially, we were concerned that Gatsby’s static approach would interfere with this — not the case! We’ve been able to code D3 in much the same way that we are used to and it works!

If you want to read further about DOM related quirks in Gatsby and how to implement D3 in the framework check out these links:

https://www.gatsbyjs.org/docs/debugging-html-builds/#how-to-check-if-window-is-defined

https://www.gatsbyjs.org/docs/porting-from-create-react-app-to-gatsby/#server-side-rendering-and-browser-apis

https://medium.com/@jeffbutsch/using-d3-in-react-with-hooks-4a6c61f1d102

2. You don’t have a server

This was another one that initially had us scratching our heads. In a classic SSR set up the client makes a request, the server compiles static assets and feeds those back. You have your client environment variables, and your server environment variables, and a clear separation between the two. In Gatsby, it’s acting as both the client and the server.

If you’ve used Create React App, Gatsby leverages two familiar libraries — Webpack’s DefinePlugin and dotenv. The workflow is somewhat similar to Create React App but you’ll need to remember two things:

  1. Variables are prefixed with GATSBY_ instead of REACT_APP_

  2. Variables not prefixed with GATSBY_ are available to your local Node process during build time

In the below example taken from the Gatsby Documentation on Environment Variables:

# .env.*
GATSBY_API_URL=https://dev.example.com/api
API_KEY=927349872349798


GATSBY_API_URL would be available to any code in your client and API_KEY would be available to your app during build time, but not included in your client code. As always, it is never a good idea to check any .env.* file into your source control.

If you need to access the Node environment that is responsible for building your application at any point Gatsby provides hooks for that using gatsby-node.js and gatsby-ssr.js. Both files are optional and well documented. We have also not found the need to dive under the hood too often, Gatsby’s default functionality has us covered!

Again, the changes Gatsby brings to the table are not too crazy, but are digressions from a typical workflow. Check out the links below to read further on how Gatsby leverages Environment Variables and Node:

https://www.gatsbyjs.org/docs/environment-variables/

https://www.gatsbyjs.org/docs/api-files/

3. You don’t have a filesystem

While this one is actually optional (you can use your regular public folder as normal if you feel like it) Gatsby encourages you to forgo a traditional file system and instead leverage it’s Gatsby Source Filesystem Plugin. We decided to follow their advice and have very much enjoyed working with GraphQL instead of relative paths.

The workflow is much more seamless, integrates well into the Gatsby environment, and feels more like coding than referencing files. We would encourage anyone wanting to develop with Gatsby to go this route as well. It does have some quirks, especially around hot reloading. These can be mitigated somewhat by setting ENABLE_GATSBY_REFRESH_ENDPOINT=1 in your .env.* file which will allow you to run the following on OSX in your terminal:

curl -X POST http://localhost:8000/__refresh

This command ostensibly refreshes GraphQL…but in practice only works some of the time. You can find the relevant documentation for refreshing GraphQL here.

We look forward to a complete implementation of hot reloading and in the meantime, it hasn’t been enough of a deterrent for us to drop Gatsby’s GraphQL filesystem. You can read more about Gatsby’s filesystem-less filesystem and their decisions to use it in their documentation:

https://www.gatsbyjs.org/docs/sourcing-from-the-filesystem/

https://www.gatsbyjs.org/docs/why-gatsby-uses-graphql/

4. Let Gatsby do the heavy lifting, but learn your tools

Gatsby offers many solutions that make building fast, responsive web applications a breeze. Two that come to mind are the Image component and the Link component. Generally speaking, you’ll almost always want to lean on Gatsby’s solution over a hand-rolled one. The framework has been meticulously designed leveraging modern API’s and is great at letting you do what you do best (code!) without worrying about the fine details of performance. However, that does not take away the importance of learning your tools. While you should embrace Gatsby's approaches, take the time to understand what’s going on under the hood and why they are so good.

Take, for example, our experience with the Image component. At first, we were thrilled at the speed it brought. However, while continuing development we noticed that the images were actually slowing down several of our pages. Digging further, we realized that Gatsby only optimizes for viewport, not container size, and additionally some of our images were simply too large. After adjusting our image queries to load specific image sizes for specific uses and compressing the images we saw that speed boost we had come to know and love snap back to life.

We also encountered some issues around deployment builds backing up and becoming “clogged” when deploying (we use Netlify — it integrates quite well with Gatsby!). Again, research revealed we could replicate their process locally by running:

gatsby clean

followed by:

gatsby build

Documentation for the “clean” and “build” commands can be found here and here, respectively.

This insight sped up our development process significantly as errors could now be caught by individual developers before being pushed to a preview deployment. While this issue is not exactly related to Gatsby, it does reinforce the perspective that while “magic” code makes your life easier and can have huge productivity benefits you should still understand what the “magic” is actually doing.

Check out the link below for areas where Gatsby provides “magic”:

https://www.gatsbyjs.org/docs/gatsby-magic/

Conclusion

Like starting any new framework, our journey with Gatsby has definitely had a few learning curves. However, overall we love our website, we love working on it, and we’re excited to add Gatsby to our toolset. In fact, we are recommending Gatsby to a client building an eCommerce website using Shopify’s API. Outside of these projects, we plan to actively support the open source development of Gatsby, share our experiences with the framework via our blog, and hope to build a boilerplate based on our own preferences to further the Gatsby community.

Oh btw

We are considering this post to be a living document and will update it if we discover any other noteworthy quirks while using Gatsby. If there is anything you feel should be mentioned, please share it in the comments. We would love to hear from you!