Sometimes all we need is a static site without all the hassles of building and configuring servers. It could be a blog, an ad campaign, a listing for an event or something simple. We require a static site generator to generate build files and render these files as is, upon request. In this article, we will be building a static site using Gatsby.js.
What is a Static Site?
Imagine going to a grocery store, all you want is on the shelf and ready to be sold. You can buy as much as you want, pay and leave. Whereas there are stores where you can buy groceries as seen on the shelf, but some items are not in the store, but in the warehouse and whenever you want to buy it, you make a request through the storekeeper who gets it for you.
These analogies represent a static site and a dynamic site respectively. Where in a static site, it’s basically WYSIWYG, but in a dynamic site there are servers which handle requests and respond with data on request. Static sites give us the benefit of speed and simplicity.
There is a host of static site generators but for this article, we will be building a static blog with Gatsby. Gatsby is a fast and robust static site generator for React. Talking about being robust, Gatsby renders dynamic content using React components into static HTML content. You will learn how to build a simple static blog using Gatsby. The blog would be able to take markdown files and render them on page load. GraphQL will be used to query our files.
Gatsby is installed in what is called starters, these are preset builds for specific purposes and make development easy. For this project, we shall be using the Gatsby default starter which is the starter for a blog. There are lots of starters and they can be found here. First, we install Gatsby CLI tool globally via npm with:
npm install -g gatsby-cli
Gatsby CLI enables us to build apps faster and comes with a development server and a hot reload function, therefore, changes made to our source files are immediately visible in our browser. We install the Gatsby default starter with:
gatsby new gatsby-blog && cd gatsby-blog
This creates our Gatsby files in the project folder `gatsby-blog` and changes the directory to that folder. To run our development server, in the console run:
The development server is hosted on `localhost:8000`
This is simply a development server. To start a production build, run the build command:
npm run build
Gatsby, like some other static site generators, employ the use of plugins to include functionalities in our blog. These plugins either extend the functionality of Gatsby (Functional plugins), create nodes for our source files to be queried by GraphQL (Source Plugins) or transform files from various formats such as markdown which is not usable by Gatsby to a form which is usable (Transformer plugin).
In addition to the default plugins installed by the starter, install:
- `gatsby-source-filesystem`: This is a source plugin we use in creating nodes for our source files.
- `gatsby-plugin-typography`: Using libraries such as bootstrap in Gatsby come with little more complexities and is difficult to customize, so we use a library `Typography.js`. Typography lets us generate typographic CSS. It also comes with awesome themes of which bootstrap is one of them.
- `typography-theme-bootstrap`: This is the custom bootstrap theme for typography. We would employ this to enable basic bootstrap styling.
- `gatsby-transformer-remark`: Transformer plugin to transform our markdown files.
Install these plugins with:
npm install --save gatsby-source-filesystem gatsby-plugin-typography typography-theme-bootstrap gatsby-transformer-remark
Now we have all our dependencies saved. Let’s get to crafting our blog.
Gatsby lets us create a layout for our blog, this helps us place elements of our blog which we would like to be consistent across all the pages of the blog such as header, navigation bars, and footers. In this blog we would require just a header to be consistent across all the pages and styling would be done inline with the inline style props.
So far our blog has two pages and an error 404 page, you can see the pages in the directory /src/pages/, remove the `page-2.js` file in `src/pages/`, we won’t be needing it. In `src/layout/index.css/`, wipe all the CSS styling in place, we wouldn’t be needing all of that for this.
In `/src/layouts/index.js`, note the imported components and packages.
Link is used in place of anchor tag and uses the ‘to” property to define a destination for the link.
Edit the blog title, as well as the background color of the header:
Now we have our layout all set. Let’s enable our typography bootstrap theme. First, create a file `typography.js` in a new folder `src/utils/`. In `typography.js`, edit the file to:
This creates a typography module to be exported. Where do we export the module to so it is accessible globally on our project? In our root directory, there is a file named `gatsby-config.js`. This is where we configure all plugins and other site configurations. In `gatsby-config.js`, we specify our typography plugin and file path, let’s also specify our `gatsby-source-filesystem` and `gatsby-transformer-remark` plugins at once:
Note: `gatsby-react-helmet` plugin enables the modification of head tags in our blog.
Creating Blog Posts
So far we have been decorating our blog a bit. Our blog is to be built in a way, content will be written in markdown and this content will be transformed and passed into our React component to be rendered. Create a folder `/src/blog-posts/` this would house our blog posts in markdown. Let’s create sample blogs posts in markdown.
Note the data between both triple dashes (`---`), this is known as frontmatter and would be used to collect blog specific data which we would like to be displayed on our page. Now we have our blog posts but so far, we can’t see them on our page, not to worry, we are getting to that next.
Using GraphQL to Fetch Data
React makes use of GraphQL amongst others to fetch data into our react components. GraphQL is a query language. We will be employing this powerful tool to query our blog-posts into our react components. Restart your development server with:
This affects all the changes and plugins added to the `gatsby-config.js` file.
A GraphQL IDE called GraphiQL can be used to view our queries and data before we pass them to our React components. GraphiQL can be accessed when our development server is running on http://localhost:8000/___graphql
Since we have the `gatsby-source-filesystem` and `gatsby-transformer-remark` plugin installed and configured in `gatsby-config.js`, we can query all markdown files in our project folder. Let’s display all our blog posts on the home screen. Edit `index.js` in `src/pages` to:
Here we passed in data fetched by GraphQL to our react component, our query? Include this at the bottom of the script:
This is our query and as we can see we fetched data from the `allMarkdownRemark` node. You can run this query starting from the `allMarkDownRemark` node to better see how data is fetched and displayed as an object.
Now we have our blog posts displayed on our home screen.
Notice that the blog posts are not sorted according to their dates, GraphQL gives us the ability to sort and filter nodes in our queries. In `src/pages/index.js` edit the allMarkdownRemark query to:
Our blog posts are sorted in descending order.
Create Blog pages
So far we have created a blog front, but what about our articles and posts, they don’t just remain on the front with just excerpts, we need to see the whole content on a different page. We shall do this programmatically so new pages are generated per post. To generate pages with Gatsby we need to:
- Create the `path` or `slug` for the page
- Create the `page`
We will use two Gatsby APIs to accomplish this, they are `onCreateNode` and `createPages` API. All we need do is simply export a function with the name of the API from `gatsby-node.js`. In the root directory, we create the file `gatsby-node.js`. Edit it to:
To create slugs of our markdown files on the MarkdownRemark node, we use the createFilePath function that ships with the `gatsby-source-filesystem`. This function finds the parent File node of our files as they contain details of our files and it creates the slugs. We use the `createNodeField` function on our `onCreateNode` API to add our new slugs to the `MarkdownRemark` node so the slugs can be queried in our components. The if statement is first used to verify if the node type is a `MarkdownRemark` before creating the slug. To view the slugs for our files you can query it in GraphiQL with:
Before we create the blog pages, let’s create a template for our blog pages. We create a file `blog-post.js` in a new directory `src/templates/`. Create the React component like:
Add the GraphQL query at the bottom with:
Now we have a template for our pages let’s create our pages with the `createPages` API. In the `gatsby-node.js` file this is included:
Above, we called the createPages API which creates the pages from the slugs we created earlier, also we specified the GraphQL queries to fetch the required data in a promise statement as well as specify the path to the blog template we created earlier. Restart the development server and we have our pages created. We can’t see it now unless you type in the file path in the URL bar.
Lastly, we set a link to each of our blog posts from our home page. In `src/pages/index.js`, each blog section is masked with an element and the to prop is set to the slug of the blog.
Also, we include the slug query in our GraphQL queries at the bottom:
We restart our development server, and when you click on any of the blog posts you get to the main article page, fast.
In this article we have built a static blog using Gatsby and also we have seen we can fetch data seamlessly using GraphQL. Gatsby allows us to utilize data from multiple sources including but not limited markdown, CSV and CMS like Drupal and Wordpress. Feel free to style your blog anyway and there are lots of styling options available, you can find them here. Also, you can work with utilizing data other aforementioned data types. Check out the source code here.
Manifold is the first independent marketplace for developer services and the easiest way to manage and share everything from JawsDB, a simple postgres database to Mailgun, an API that makes sending and receiving email dead simple.
For more info visit Manifold.co or follow us on twitter. This post is part of the Manifold Content program. Want to write for us?