Abstract: Migrating a static site to Gatsby is pretty simple. I’ll walk through how I did it and the pitfalls along the way.
Gatsby 1.0 was just recently published and I got excited. I’ve been excited about static sites for a while, especially in combination with React. I’ve spoken publicly about building static sites with React and two of my top repositories on GitHub are just for building static sites with React…
So I was pretty pumped to see Gatsby hit 1.0. And so far it has not disappointed.
OK, enough context! Let’s migrate something. I chose to start by migrating my personal site since it’s already built with React and is literally 1 page. Here it is—the entire site:
Step 1 is to install Gatsby. I’m also adding
gatsby-link and the react helmet plugin because I knew I would need them:
gatsby-config.js file in the project root and drop the following into it:
Run Gatsby to make sure everything is working.
This will start a local server. Point your browser to whatever local port it gives you and try it out. You should see a Gatsby 404 page. This is because it expects your source code to be in the
src/ directory. In my project all my source is in my
client/ directory so Gatsby has nothing to find.
However, when I loaded up the dev server in the browser I was greeted by this hot error 😐 (note, this may well not happen for you):
If you do see something like that not to worry. It’s an issue with conflicting versions of react-proxy probably resulting from differing versions of react-hot-loader. You can check this with
npm ls react-proxy. Anyway, blow away your
node_modules folder and install from scratch. Also check your
package.json dependencies to make sure you aren’t depending on any hot loading packages. In fact, now would be a good time to remove almost all your devDependencies from package.json. Gatsby is an entire build pipeline that will take care of most things for you, so consider critically every one of your dev dependencies. After manually pruning mine looked like this:
Yup, all loaders and plugins are gone. Gatsby isn’t even in this list because it’s a full-blown dependency, not just a devDependency.
So, once you’ve cleared out your old dev dependencies do a fresh install. Then restart the dev server:
You should see the correct 404 page in your browser.
Here is the structure of my source code before and after the migration. I’m putting them together here for easy comparison, but I will walk through all of what changed.
Let’s start with the quick wins:
- We no longer need webpack config so remove them:
- Gatsby expects everything under the
srcdirectory so let’s make that happen
mv client src
mkdir -p src/layouts
mkdir -p src/pages
Now let’s talk about those directories:
src/layouts/: Is where you put wrapper components. Markup that will generally “go around” your individual pages. This usually means headers and footers.
src/pages/: This is the meat of a Gatsby site. It’s where the content goes. The rule of thumb is that you should construct your
src/pagesdirectory to build your URLs.
For my purposes I had one layout and one index page. Of course I also wanted a 404 page so I created all three. This meant a bit of refactoring since I had everything together in
I’m migrating from React Router so let’s take a quick look at my route config:
Pretty simple right? When migrating over to Gatsby these components had a direct mapping to files in the new structure:
Migrating your components will be specific to your project so I’ll just point you to the minimal gatsby example which includes all the relevant files: examples/no-plugins.
Up until this point I had commented out all my CSS and Stylus imports since I figured they might cause issues. In the case of CSs this fear was unfounded. Gatsby does a great job of handling CSS imports right out of the box.
Time to write a plugin. I’ll skip over most of the details here since you view the source code of the plugin I wrote directly. But a neat feature of Gatsby is that you create a
plugins/ directory in your own project and extend Gatsby right there. This is a really nice developer experience and it makes it easy to write a plugin that can then be contributed back to the Gatsby community later.
So, after all the changes above and creating the stylus plugin my project looked like this:
And it worked 🎉.
As for the stylus plugin, there’s currently a pull request to get it merged in. Once it’s merged you can use stylus by just installing the plugin:
After getting everything working properly the last step was to add a few things I had neglected while refactoring:
Analytics: I’ve been using Google Analytics on my site all along so I needed to get that working I just needed to add the
Titles and meta tags
react-helmet is great for this and Gatsby recognizes it. Just add the
gatsby-plugin-react-helmet and your good to go. See the react-helmet docs for how to actually use it.
That’s all. If you have an questions you can leave a commend or find me on twitter.
P.S. You may have noticed that this was a super simple site (one page!) and that this is “Part 1”. I plan to migrate this blog you’re reading right now to Gatsby and do a Part 2 write up about that. It will be a much more real-world use case of Gatsby and will use the awesome GraphQL infrastructure Gatsby gives you 😋