How to Build Your Coding Blog From Scratch Using Gatsby and MDX
Are you a developer looking to start a blog to share your knowledge, document your learning journey, and build your online presence? Using a static site generator like Gatsby with MDX support is a great option.
Gatsby is a blazing-fast static site generator built with React and GraphQL. It allows you to create highly optimized sites that load quickly. And with the MDX plugin, you can write your posts using a combination of Markdown and React components – perfect for embedding interactive code samples, charts, and more directly in your content.
In this guide, I‘ll walk you through the process of building your own developer blog from the ground up with Gatsby and MDX. No prior experience with Gatsby is required, though it helps to be familiar with React and GraphQL concepts. Let‘s get started!
Intro to Gatsby
First, what exactly is Gatsby? Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps.
It offers features like:
- Pre-rendering static HTML for ultra-fast loading
- Pull data into pages from any source
- Built-in support for things like code splitting, image optimization, and data prefetching
- A large ecosystem of plugins
- Seamless deployment
Some notable sites built with Gatsby include Impossible Foods, Nike Mexico eCommerce, Airbnb Engineering & Data Science, and more.
Setting Up a New Gatsby Site
Let‘s begin by setting up a new Gatsby project. Make sure you have the latest version of Node and npm installed.
Open up your terminal and install the Gatsby CLI:
npm install -g gatsby-cli
Next, navigate to the directory where you want to create your project and use the CLI to set up a new site:
gatsby new my-coding-blog
Select the "hello world" starter when prompted. This will generate a basic boilerplate Gatsby project.
Once the process finishes, navigate into the directory and start the local development server:
cd my-coding-blog
gatsby develop
You can now view your shiny new Gatsby site at http://localhost:8000
!
Adding Blog Pages
Now that we have a working Gatsby site, let‘s start turning it into a blog.
In Gatsby, pages automatically become URLs based on their file name. For example, src/pages/about.js
would be accessible at yoursite.com/about
.
We‘ll start by creating:
- A page for blog posts at
src/pages/blog.js
- A page for an individual post at
src/templates/post.js
Your blog.js
page could look something like this to start:
import React from ‘react‘
import { Link, graphql } from ‘gatsby‘
import Layout from ‘../components/layout‘
const BlogPage = ({ data }) => {
const posts = data.allMdx.edges
return (
<Layout>
<div>
{posts.map(({ node }) => (
<div key={node.id}>
<Link to={node.fields.slug}>
<h2>{node.frontmatter.title}</h2>
</Link>
<p>{node.frontmatter.date}</p>
<p>{node.excerpt}</p>
</div>
))}
</div>
</Layout>
)
}
export const query = graphql`
query {
allMdx(sort: { fields: [frontmatter___date], order: DESC }) {
edges {
node {
id
frontmatter {
date(formatString: "MMMM D, YYYY")
title
}
fields {
slug
}
excerpt
}
}
}
}
`
export default BlogPage
This renders a list of all your blog posts, sorted by date. The graphql
query fetches the post title, date, excerpt, and slug (URL).
The post.js
template would define the layout of an individual post:
import React from ‘react‘
import { graphql } from ‘gatsby‘
import { MDXRenderer } from ‘gatsby-plugin-mdx‘
import Layout from ‘../components/layout‘
const PostTemplate = ({ data }) => {
const post = data.mdx
return (
<Layout>
<article>
<MDXRenderer>{post.body}</MDXRenderer>
</article>
</Layout>
)
}
export const query = graphql`
query($slug: String!) {
mdx(fields: { slug: { eq: $slug } }) {
body
frontmatter {
title
}
}
}
`
export default PostTemplate
Here we‘re using the MDXRenderer
component to render the body content of the post which is written in MDX.
Writing Blog Posts with MDX
Next, let‘s add some actual blog content. Create a new directory at content/posts
. This is where your MDX files will live.
MDX lets you use JSX components and React code alongside Markdown syntax. A basic example post could look like:
---
title: My First Post
date: 2023-05-23
---
# Hello world!
This is my first post written in MDX.
I can use Markdown features like **bold**, *italics*,
- Lists
- [ ] Task lists
As well as JSX components:
<Button>Click me</Button>
Gatsby needs to know about your MDX files in order to turn them into pages. We‘ll do this by configuring the gatsby-source-filesystem
plugin.
Gatsby Plugins
Gatsby has a robust plugin system to add all sorts of extra functionality to your site. Several plugins are essential for adding a blog.
Install the following packages:
npm install gatsby-source-filesystem gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
And add them to your gatsby-config.js
:
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content/posts`,
name: `posts`,
},
},
`gatsby-plugin-mdx`,
]
}
The gatsby-source-filesystem
plugin will load your MDX files so that GraphQL can query them, while gatsby-plugin-mdx
processes MDX files.
A few other useful Gatsby plugins to consider adding:
gatsby-remark-images
: Optimize images in Markdowngatsby-plugin-sharp
: Process imagesgatsby-remark-prismjs
: Adds syntax highlighting to code blocksgatsby-plugin-sitemap
: Automatically generate a sitemapgatsby-plugin-feed
: Generate an RSS feedgatsby-plugin-react-helmet
: Add metadata to the<head>
Install and configure them based on the README instructions for each plugin.
Querying Posts with GraphQL
Once you‘ve added some MDX posts, you can query them with GraphQL. The GraphQL query we wrote earlier in blog.js
will now have data available.
Try visiting http://localhost:8000/___graphql
to explore the available data with the GraphiQL IDE. This is a great way to build queries visually.
Some useful queries might be:
- Fetch the N most recent posts
- Fetch all posts with a certain tag
- Group posts by year
- Paginate posts
For example, here‘s how you could modify the blog.js
query to only fetch the 5 most recent posts:
query {
allMdx(
sort: { fields: [frontmatter___date], order: DESC }
limit: 5
) {
# ...
}
}
Programmatically Creating Pages
In order to actually turn your MDX files into pages, you need to implement Gatsby‘s createPages
Node API. This lets you programmatically create a page for each post.
In gatsby-node.js
:
const path = require(`path`)
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions
const result = await graphql(`
query {
allMdx {
edges {
node {
id
fields {
slug
}
}
}
}
}
`)
if (result.errors) {
reporter.panicOnBuild(‘🚨 ERROR: Loading "createPages" query‘)
}
const posts = result.data.allMdx.edges
posts.forEach(({ node }, index) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/post.js`),
context: { id: node.id },
})
})
}
This queries all your MDX files, then loops through to create a page for each one using the post.js
template. The URL is based on the slug
field (which comes from the file name).
Styling the Blog
Of course, you‘ll want to make your blog look nice with some styling. You can use regular CSS, Sass, or a CSS-in-JS library like styled-components or Emotion.
To use a CSS stylesheet, create a file like src/styles/global.css
and import it in your gatsby-browser.js
:
import ‘./src/styles/global.css‘
Now you can add some base styles and classes that will be applied to every page.
For more modular styles, you can use CSS Modules or a library like styled-components to scope styles to individual components.
Some things to consider when designing your blog:
- Use a readable, sufficiently large font size
- Limit the width of your content for readability
- Add margin and padding to give your content breathing room
- Ensure there‘s sufficient color contrast
- Highlight your code snippets
- Create mobile-friendly, responsive styles
Adding Extras
With the base of your blog finished, consider adding some extra features:
-
Email newsletter: Let readers sign up to get notified of new posts. You can use a service like Mailchimp or Convertkit to manage your list and send emails. Gatsby has plugins to help with the integration.
-
Comments: Add a commenting system so readers can share their thoughts on your posts. Options include Disqus, Commento, Facebook Comments, and more.
-
RSS Feed: Use the
gatsby-plugin-feed
plugin so readers can subscribe via their favorite feed reader. -
Social sharing: Make it easy for readers to share your posts on social media with share buttons.
-
Related posts: Suggest other relevant content at the end of each post to keep readers engaged. You can use the
gatsby-plugin-related-posts
plugin. -
Search: Help readers find content with a search bar. Tools like Algolia make it easy to add search functionality.
Optimizing and Deploying
Finally, make sure your blog is optimized and deployed.
Gatsby takes care of a lot of performance optimizations automatically, but a few extra things you can do:
- Use
gatsby-plugin-offline
to add a service worker and make your blog work offline - Add lazy loading for images below the fold
- Minimize and lazy load third-party scripts
- Use
gatsby-plugin-purgecss
to remove unused CSS
Deploying a Gatsby blog is straightforward. Because Gatsby is a static site generator, you can host it for free on services like Netlify or Vercel.
Netlify has a plugin called netlify-plugin-gatsby
that makes the setup process extremely simple. After connecting your Git repository, Netlify will automatically build and deploy your site any time you push changes.
Learn More
To dive deeper into building a Gatsby blog, check out these additional resources:
- Gatsby documentation
- Gatsby tutorial
- Gatsby blog starter
- How Gatsby works with GitHub pages
- Building a developer blog with Gatsby
- How to build a Gatsby blog with Netlify CMS
With the power of Gatsby and the flexibility of MDX, you can create a lightning-fast, highly customized blog to share your developer journey. The skills you learn building it will also translate to creating other types of Gatsby sites.
Happy blogging!