The Gatsby Migration, pt.2 - Dumb Pages

01 February 2020

Updated: 03 September 2023

Introduction

In the last post we looked setting up an application with a few basic routes. These routes were all assigned to Components in the src/pages directory.

This post will be going throught the Gatsby Setup necessary in order to migrate our current site to Gatsby, we will be looking at the second step in the process that was outlined in the last post:

  1. Creating the initial React App
  2. Rendering the “Dumb” pages with Gatsby (This post)
  3. Rendering the “Smart” page with Gatsby

Getting Ready

In order to Gatsbyify the application, there are three steps that we will need to take before we can start updating our pages to work with the new system

  1. Update folder structure
  2. Install Gatsby
  3. Create the necessary Gatsby Config files

Update Folder Structure

Gatsby Builds are placed into the public directory. This currently is the output directory of a React build if we are using the standard React configuration

Before we do anything more we should rename our public directory to static as this is what Gatsby uses for static files, and then make a git commit before we add the public directory to our .gitignore

Now we need to add the following lines to the end of our .gitignore file so that we do not track the gatsby build files:

.gitignore

Terminal window
1
# gatsby
2
public
3
.cache

Install Gatsby

To add Gataby to our project we need to add the gatsby package from npm as a dependency to our project. From the project’s root directory run:

1
yarn add gatsby

Next we’ll add/update the following commands in our package.json file so that we can start the Gatsby Dev Server as well as build the application

package.json

1
"scripts": {
2
"start": "gatsby develop",
3
"build": "gatsby build",
4
"clean": "gatsby clean",
5
...
6
},

Create Config Files

In order to enable gatsby we need to add the gatsby-config.js file to our root directory, we can use the starter file with the following content, as it currently stands this doesn’t do anything

gatsby-config.js

1
module.exports = {
2
plugins: [],
3
}

Next we’ll create an html.js file in the src directory with any relevant content from your index.html file if any of it has been updated. Also be sure to remove the %PUBLIC_URL% stuff from the file content

The html.js file needs to be a React Component with the following basic structure for a standard CRA app

src/html.js

1
import React from 'react'
2
import PropTypes from 'prop-types'
3
4
export default function HTML(props) {
5
return (
6
<html {...props.htmlAttributes}>
7
<head>
8
<meta charSet="utf-8" />
9
<link rel="shortcut icon" href="/favicon.png" />
10
<meta name="viewport" content="width=device-width, initial-scale=1" />
11
<meta name="theme-color" content="#ffffff" />
12
13
<link rel="manifest" href="/manifest.json" />
14
15
<title>React App</title>
16
17
<script
18
dangerouslySetInnerHTML={{
19
__html: `
20
// Any scripts that need to be included in the HTML itself
21
// Like tracking code, etc.
22
console.log("Inline Javascript")
23
`,
24
}}
25
></script>
26
27
{props.headComponents}
28
</head>
29
<body {...props.bodyAttributes}>
30
{props.preBodyComponents}
31
<div
32
key={`body`}
33
id="___gatsby"
34
dangerouslySetInnerHTML={{ __html: props.body }}
35
/>
36
{props.postBodyComponents}
37
</body>
38
</html>
39
)
40
}
41
42
HTML.propTypes = {
43
htmlAttributes: PropTypes.object,
44
headComponents: PropTypes.array,
45
bodyAttributes: PropTypes.object,
46
preBodyComponents: PropTypes.array,
47
body: PropTypes.string,
48
postBodyComponents: PropTypes.array,
49
}

You can add or remove any elements in that file as per your specific requirements but most of the time the above should be fine

Now that we have updated the index.js file delete the static/index.html file you can run the Gatsby Dev Server

1
yarn clean
2
yarn start

Your application should now be running on http://localhost:8000/, if started correctly you should see the Gatsby Development 404 Page:

Development 404 Page

Gatsby.js development 404 page

There’s not a page yet at /

Create a React.js component in your site directory at src/pages/index.js and this page will automatically refresh to show the new page component you created.

If you were trying to reach another page, perhaps you can find it below.

Pages (4)

Search:

  • /Blog/
  • /Home/
  • /NotFound/
  • /Post/

Page Setup

From the Development 404 Page we can see that Gatsby has found our previously created pages - this is because Gatsby looks for pages in the pages directory, however when we click on a the links we will notice the following:

  1. Home and 404 render correctly
  2. Blog results in an error message
  3. Post results in an error message (we will address this page in the next post)
  4. Routes aren’t aligned with our initial setup
  5. Components no longer have the layout we setup in the App.js file

These are, for the most part, easy problems to solve

Fix the Blog Error Message

If we look at the Blog page we will see that there is an issue with the Page render, this is because we need to change the Link components to be imported from gatsby instead of react-router-dom because with Gatsby we are no longer using the React Router

Blog.js

1
import { Link } from 'gatsby'

Fix the Routes

We can also see that our routes are capitalized which is not what we want. Gatsby uses the file organization to do routing, so in order to correct our routes to align what we defined previously in our App.js we will first need to rename our files:

ComponentRouteOld NameNew Name
Home/Home.jsindex.js
Blog/blogBlog.jsblog.js
NotFound/*NotFound.js404.js

We’re not going to handle the Post component for now because this uses a dynamic route which is something I’ll cover in the next part of this series

You should stop and restart the Gatsby Dev server with:

1
yarn clean
2
yarn start

When the page loads up we should now see our Home content rendered on the / route

Fix the Layout

When we were using the standard React Routing we made use of the App component to wrap our page routes as well as our navigation. We’ll convert our App.js file into a component that we can use in our other pages

  1. Remove the Router and Switch
  2. Update the Links to use gatsby instead of react-router-dom
  3. Add the children input parameter
  4. Render the children in the main section
  5. Remove unused imports

App.js

1
import React from 'react'
2
import './App.css'
3
import { Link } from 'gatsby'
4
5
const App = ({ children }) => (
6
<div className="App">
7
<header>
8
<nav>
9
<h1>My Website Title</h1>
10
<Link to="/">Home</Link>
11
<Link to="/blog">Blog</Link>
12
</nav>
13
</header>
14
<main>{children}</main>
15
</div>
16
)
17
18
export default App

Use the Layout

Now that we’ve essentially created a Layout component in the form of the App component we can use it to wrap the pages that we’ve exported. We can do this for the Home page like so:

index.js

1
import React from 'react'
2
import App from '../App'
3
4
const Home = () => (
5
<App>
6
<div className="Home">
7
<h1>Home</h1>
8
<p>This is the Home page</p>
9
</div>
10
</App>
11
)
12
13
export default Home

The same applies for the blog and 404 pages

Blog

blog.js

1
import React from 'react'
2
import { Link } from 'gatsby'
3
import App from '../App'
4
5
const Blog = () => (
6
<App>
7
<div className="Blog">
8
<h1>Blog</h1>
9
<p>This is the Blog page</p>
10
<div>
11
<Link to="/blog/post-1">Post 1</Link>
12
</div>
13
<div>
14
<Link to="/blog/post-2">Post 2</Link>
15
</div>
16
</div>
17
</App>
18
)
19
20
export default Blog
404

404.js

1
import React from 'react'
2
import App from '../App'
3
4
const NotFound = () => (
5
<App>
6
<div className="NotFound">
7
<h1>404</h1>
8
<p>Page Not Found</p>
9
</div>
10
</App>
11
)
12
13
export default NotFound

Fix the CSS

Before we can use the App component we need to add the gatsby-plugin-postcss and postcss-preset-env plugins so that Gatsby knows how to interpret the default create-react-app method of importing our CSS into a component

Stop the Dev Server and install the required packages:

1
yarn add gatsby-plugin-postcss postcss-preset-env

We then need to update the gatsby-config.js file to use the plugin we just added:

gatsby-config.js

1
module.exports = {
2
plugins: [
3
{
4
resolve: `gatsby-plugin-postcss`,
5
options: {
6
postCssPlugins: [require(`postcss-preset-env`)({ stage: 0 })],
7
},
8
},
9
],
10
}

If you start the application now you’ll notice that the font is not correct, this is because we specify the font styles in the index.css file. In order to fix this we need to import the index.css file into our application, in the default React application this is done via the src/index.js file, but since we don’t use that to load up the application anymore we need to create another file to do that with Gatsby

In the root directory create a file called gatsby-browser.js, in this we just need to import the index.css file:

gatsby-browser.js

1
import './src/index.css'

You can now run the following commands and start up the application:

1
yarn clean
2
yarn start

Assuming everything went as planned the application should start up correctly and the styling from our index.css file will be correctly applied

Summary

By now we have completed the first part of the migration process - converting our static pages to use Gatsby - by taking the following steps:

  1. Updating our file structure to better align with Gatsby
  2. Create the relevant Gatsby config files
  3. Update our Link usage
  4. Update our Routing
  5. Use a shared layout component
  6. Fixing the CSS to work with Gatsby

In the next part we’ll look at how we can go about providing the data needed for our Post component using GraphQL and show our posts. We’ll also look at how we can pre-process the data that we provide to our component so that we can enhance our content while improving our content creation process

Nabeel Valley