Building a Blog with Gatsby and React
This tutorial will guide you through the process of building a blog using Gatsby and React. We will start by setting up the project, then move on to building the blog layout, creating blog posts, adding navigation, styling the blog, and finally deploying it to production.
Introduction
Gatsby is a static site generator that uses React as its frontend framework. React is a JavaScript library for building user interfaces. Together, Gatsby and React provide a powerful combination for creating fast and interactive blogs.
Setting Up the Project
To get started, you'll need to have Node.js installed on your machine. Once you have Node.js installed, you can proceed with the following steps.
Installing Gatsby
To install Gatsby, open your terminal and run the following command:
npm install -g gatsby-cli
This will install the Gatsby CLI globally on your machine.
Creating a new Gatsby project
Next, navigate to the directory where you want to create your new Gatsby project and run the following command:
gatsby new my-blog
This will create a new Gatsby project with the name "my-blog".
Adding React to the project
By default, Gatsby comes with React already integrated. However, if you want to add additional React components to your blog, you can do so by installing the required packages. For example, to install the React Router package, run the following command:
npm install react-router-dom
This will install React Router, which will be used later for creating navigation in our blog.
Building the Blog Layout
Now that we have our project set up, let's start building the layout for our blog.
Creating the header component
First, let's create a header component that will be displayed at the top of every page. Create a new file called "Header.js" in the "src/components" directory and add the following code:
import React from "react";
const Header = () => {
return (
<header>
<h1>My Blog</h1>
</header>
);
};
export default Header;
In this code, we import React and create a functional component called Header. The component returns a header element with the title of our blog.
Designing the main content area
Next, let's design the main content area of our blog. Create a new file called "Layout.js" in the "src/components" directory and add the following code:
import React from "react";
import Header from "./Header";
const Layout = ({ children }) => {
return (
<div>
<Header />
<main>{children}</main>
</div>
);
};
export default Layout;
In this code, we import React and the Header component. We create a functional component called Layout that takes a prop called "children", which represents the content that will be displayed inside the main content area. The component returns a div element with the header component at the top and the "children" prop wrapped inside a main element.
Implementing the sidebar
Now, let's implement a sidebar component that will be displayed on the left side of our blog. Create a new file called "Sidebar.js" in the "src/components" directory and add the following code:
import React from "react";
const Sidebar = () => {
return (
<aside>
<h3>Categories</h3>
<ul>
<li>Category 1</li>
<li>Category 2</li>
<li>Category 3</li>
</ul>
</aside>
);
};
export default Sidebar;
In this code, we create a functional component called Sidebar. The component returns an aside element with a heading and a list of categories. You can customize the categories according to your blog's needs.
To display the sidebar component in our layout, open the "Layout.js" file and update it as follows:
import React from "react";
import Header from "./Header";
import Sidebar from "./Sidebar";
const Layout = ({ children }) => {
return (
<div>
<Header />
<div>
<Sidebar />
<main>{children}</main>
</div>
</div>
);
};
export default Layout;
In this code, we import the Sidebar component and add it inside a div element, alongside the main content area.
Creating Blog Posts
Now that we have our blog layout set up, let's move on to creating blog posts.
Setting up a blog post template
First, let's create a template for our blog posts. Create a new file called "BlogPostTemplate.js" in the "src/templates" directory and add the following code:
import React from "react";
const BlogPostTemplate = () => {
return (
<div>
<h2>Blog Post Title</h2>
<p>Blog post content goes here...</p>
</div>
);
};
export default BlogPostTemplate;
In this code, we create a functional component called BlogPostTemplate. The component returns a div element with a title and some placeholder content. Later, we will fetch the actual blog post data and render it dynamically.
Fetching blog post data
To fetch the blog post data, we will use GraphQL. Gatsby has built-in support for GraphQL, which allows us to query our data directly from our components.
Create a new file called "gatsby-node.js" in the root directory of your project and add the following code:
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`);
if (result.errors) {
reporter.panic("Error creating blog posts", result.errors);
return;
}
const blogPostTemplate = require.resolve("./src/templates/BlogPostTemplate.js");
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.slug,
component: blogPostTemplate,
context: {
slug: node.frontmatter.slug,
},
});
});
};
In this code, we export a function called "createPages" that takes some parameters, including "actions", "graphql", and "reporter". Inside this function, we use the "graphql" function to query all the markdown files in our project and retrieve their slugs. We then use the "createPage" function to create a new page for each blog post, using the "BlogPostTemplate" component as the template and passing the slug as a context variable.
Rendering blog post content
Now that we have our blog post template and data, let's render the actual blog post content.
Open the "BlogPostTemplate.js" file and update it as follows:
import React from "react";
import { graphql } from "gatsby";
const BlogPostTemplate = ({ data }) => {
const { markdownRemark } = data;
const { frontmatter, html } = markdownRemark;
return (
<div>
<h2>{frontmatter.title}</h2>
<div dangerouslySetInnerHTML={{ __html: html }}></div>
</div>
);
};
export const query = graphql`
query($slug: String!) {
markdownRemark(frontmatter: { slug: { eq: $slug } }) {
frontmatter {
title
}
html
}
}
`;
export default BlogPostTemplate;
In this code, we import the "graphql" function from "gatsby" and use it to query the blog post data. We extract the title and HTML content from the "markdownRemark" object, which represents the blog post data. We then render the title and the HTML content using JSX.
Adding Navigation
To make our blog more user-friendly, let's add navigation links.
Creating a navigation component
First, let's create a navigation component that will be displayed at the top of every page. Create a new file called "Navigation.js" in the "src/components" directory and add the following code:
import React from "react";
import { Link } from "gatsby";
const Navigation = () => {
return (
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
);
};
export default Navigation;
In this code, we import the "Link" component from "gatsby" and create a functional component called Navigation. The component returns a navigation element with a list of links. You can customize the links according to your blog's needs.
Implementing navigation links
To display the navigation component in our layout, open the "Layout.js" file and update it as follows:
import React from "react";
import Header from "./Header";
import Sidebar from "./Sidebar";
import Navigation from "./Navigation";
const Layout = ({ children }) => {
return (
<div>
<Header />
<div>
<Navigation />
<Sidebar />
<main>{children}</main>
</div>
</div>
);
};
export default Layout;
In this code, we import the Navigation component and add it before the sidebar component in our layout.
Adding active link styling
To highlight the active link in our navigation, we can use CSS-in-JS with styled-components.
First, install the styled-components package by running the following command:
npm install styled-components
Next, create a new file called "NavLink.js" in the "src/components" directory and add the following code:
import styled from "styled-components";
import { Link } from "gatsby";
const StyledNavLink = styled(Link)`
color: ${({ active }) => (active ? "red" : "black")};
font-weight: ${({ active }) => (active ? "bold" : "normal")};
`;
export default StyledNavLink;
In this code, we import the "styled" function from "styled-components" and the "Link" component from "gatsby". We create a new styled component called "StyledNavLink" that extends the "Link" component. The styled component takes an "active" prop and applies different styles based on its value.
To use the styled component in our navigation, open the "Navigation.js" file and update it as follows:
import React from "react";
import StyledNavLink from "./NavLink";
const Navigation = () => {
return (
<nav>
<ul>
<li>
<StyledNavLink to="/" activeClassName="active" exact>
Home
</StyledNavLink>
</li>
<li>
<StyledNavLink to="/about" activeClassName="active">
About
</StyledNavLink>
</li>
</ul>
</nav>
);
};
export default Navigation;
In this code, we import the StyledNavLink component and use it instead of the regular Link component. We also add the "activeClassName" prop to highlight the active link.
Styling the Blog
To make our blog visually appealing, let's style it using CSS-in-JS with styled-components.
Using CSS-in-JS with styled-components
Styled-components allows us to write CSS directly inside our JavaScript code. It provides a convenient way to create reusable and scoped styles for our components.
To demonstrate CSS-in-JS with styled-components, let's create a simple theme for our blog.
Create a new file called "theme.js" in the "src" directory and add the following code:
const theme = {
colors: {
primary: "#007bff",
secondary: "#6c757d",
danger: "#dc3545",
},
};
export default theme;
In this code, we define a theme object with some color variables.
Next, install the styled-components package by running the following command:
npm install styled-components
Now, let's use styled-components to style our blog.
Open the "Header.js" file and update it as follows:
import React from "react";
import styled from "styled-components";
const StyledHeader = styled.header`
background-color: ${({ theme }) => theme.colors.primary};
color: white;
padding: 1rem;
`;
const Header = () => {
return (
<StyledHeader>
<h1>My Blog</h1>
</StyledHeader>
);
};
export default Header;
In this code, we import the "styled" function from "styled-components" and create a new styled component called "StyledHeader". We use the styled component to style the header element by applying a background color, text color, and padding.
Customizing the blog's theme
To use the theme in our styled components, we need to wrap our application with the "ThemeProvider" component from styled-components.
Open the "gatsby-browser.js" file in the root directory of your project and update it as follows:
import React from "react";
import { ThemeProvider } from "styled-components";
import theme from "./src/theme";
export const wrapRootElement = ({ element }) => (
<ThemeProvider theme={theme}>{element}</ThemeProvider>
);
In this code, we import the "ThemeProvider" component from "styled-components" and the "theme" object from our "theme.js" file. We wrap the root element of our application with the "ThemeProvider" and pass the theme object as a prop.
Adding responsive design
To make our blog responsive, we can use CSS media queries with styled-components.
Open the "Layout.js" file and update it as follows:
import React from "react";
import Header from "./Header";
import Sidebar from "./Sidebar";
import Navigation from "./Navigation";
import styled from "styled-components";
const StyledLayout = styled.div`
display: flex;
@media (max-width: 768px) {
flex-direction: column;
}
`;
const StyledMain = styled.main`
flex-grow: 1;
`;
const Layout = ({ children }) => {
return (
<div>
<Header />
<StyledLayout>
<Navigation />
<Sidebar />
<StyledMain>{children}</StyledMain>
</StyledLayout>
</div>
);
};
export default Layout;
In this code, we create two new styled components: "StyledLayout" and "StyledMain". The "StyledLayout" component applies a flex layout to its children and changes the direction to column when the screen width is less than or equal to 768 pixels. The "StyledMain" component ensures that the main content area takes up the remaining space.
Deploying the Blog
Once you have finished building your blog, it's time to deploy it to production.
Generating a production build
To generate a production build of your blog, open your terminal and navigate to the root directory of your project. Run the following command:
gatsby build
This command will generate a production-ready build of your blog in the "public" directory.
Choosing a hosting provider
There are several hosting providers you can choose from to deploy your Gatsby blog. Some popular options include Netlify, Vercel, and AWS Amplify.
Deploying the blog to production
To deploy your Gatsby blog to production, you can follow the deployment instructions provided by your chosen hosting provider. The exact steps may vary depending on the provider you choose.
Conclusion
In this tutorial, we have learned how to build a blog using Gatsby and React. We started by setting up the project, then built the blog layout, created blog posts, added navigation, styled the blog using CSS-in-JS with styled-components, and finally deployed the blog to production. By following this tutorial, you should now have a basic understanding of how to build a blog with Gatsby and React. Happy coding!