Skip to main content
View plugin on GitHub
See starters using this

@nickymeuleman/Gatsby Theme Blog

A Gatsby theme for creating a blog. Check out the live demo.

The default styling for the list of blogposts looks like this:

And the default styling for a single blogpost:

The lighthouse score for most pages looks like this:

Straight 100s

What you get from this theme

  • A plug and play feature rich blog platform


To use this theme in your Gatsby sites:

  1. Install the theme

    npm install --save @nickymeuleman/gatsby-theme-blog
  2. Add the theme to your gatsby-config.js:

    module.exports = {
      plugins: ["@nickymeuleman/gatsby-theme-blog"],
  3. Start your site

    gatsby develop
  4. Add an authors file and create a post! Instructions/details in the Usage section


Theme options

Key Default value Description
basePath "" Root url for this theme. eg: blog
contentPath "data/posts" Folder Location to house individual blog post-folders
assetPath "data/assets" Folder location to house extra assets (like the author file.)
pagination undefined Optional object, enables pagination if provided

pagination options

Key Default value Description
postsPerPage 10 Amount of posts per paginated page
prefixPath "" Optional string. Prefixes numbers from paginated pages. eg: page

Example usage

// gatsby-config.js
module.exports = {
  plugins: [
      resolve: "@nickymeuleman/gatsby-theme-blog",
      options: {
        contentPath: "posts",
        assetPath: "assets",
        basePath: "blog",
        pagination: {
          postsPerPage: 10,
          prefixPath: "page",

Additional configuration

In addition to the theme options, there are a handful of items you can customize via the siteMetadata object in your site’s gatsby-config.js

// gatsby-config.js
module.exports = {
  siteMetadata: {
    // Used for the site title, SEO, and header component title.
    title: `My Blog Title`,
    // Used for SEO
    description: `My site description...`,
    // Used for SEO and as default if an author has no twitter defined
    social: {
      twitter: `@NMeuleman`,

Adding blog posts

In the folder that was created for the contentPath (data/posts by default). Create a folder to hold a blog post. Unless a slug is provided, the title of this folder will serve as the slug for the blogpost. Inside that folder, an index.mdx or file will be the blog post itself. Along this file can be several different files specific to that blogpost (e.g. images) If no date is specified, the date the .md(x) file was created will serve as the date for the blogpost.

NOTE: If you dislike having a folder per blogpost, loose .md(x) files are also supported. Place them inside the folder created for contentPath. The title of the file will then serve as the slug of the blogpost if a slug not specified in the post’s slug field.

Example folder tree

└── data
    ├── assets
    │   ├── authors.json
    │   └── image-used-often.jpg
    └── posts
        ├── my-first-post
        │   ├── index.mdx
        │   ├── coverPhoto.jpg
        │   ├── boop.png
        │   └── infinite-boop.gif
        └── my-second-post
            ├── f1-car.jpg
            └── speed-data.svg

Adding authors

In the folder that was created for the assetPath (data/assets by default). Create a file called authors.json or authors.yaml. This file (or files, both formats can work together) holds an array of author objects.

Anatomy of an authors file

An authors file contains a top level array filled with object describing individual authors. An author can have several different field with information specific to them.

Key Value Required Description
shortName string yes unique identifier for the author, used in author field for blog posts
name string yes full name eg. “Nicky Meuleman”
twitter string no twitter handle without @

Anatomy of a blogpost

The blogpost itself (.md or .mdx file for now, others coming soon) can have several different fields with extra information. In .md or .mdx files these fields are set via the frontmatter.

Key Value Required Description
title string no title of your blogpost
date date string no the date tied to the post
canonicalUrl full url string no Canonical url
authors array of shortName strings no Authors of the post.
Should not be used in combination with the author key.
author shortName string no Author of the post.
Should not be used in combination with the authors key.
tags array of tag strings no tags for this post
keywords array of keyword strings no keywords for SEO
cover relative path to cover image no displayed as cover image, in social cards
published boolean, defaults to true no include post in production
slug string no the last part of the URL for this post

Components used in this theme.

Overwriting these with your own is highly encouraged. This can be done via component shadowing.

Query components

These components house the Gatsby template-query. They lightly transform that data and pass it on to the corresponsing Page component. Changes to these might require changes to the corresponding Page components because of that. Location to shadow: @nickymeuleman/gatsby-theme-blog/templates/<component-name>

  • BlogPostQuery
  • BlogPostListQuery
  • TagQuery
  • TagListQuery
  • AuthorQuery
  • AuthorListQuery

Page components

These components render an entire page. Each component is wrapped in the Layout component that centers the content and adds the Header. Location to shadow: @nickymeuleman/gatsby-theme-blog/components/<component-name>

  • BlogPostPage
  • BlogPostListPage
  • TagPage
  • TagListPage
  • AuthorPage
  • AuthorListPage

Regular components

These components are used by the Page components Location to shadow: @nickymeuleman/gatsby-theme-blog/components/<component-name>

  • PostCard
  • PostExtra
  • Pagination

Mdx components

These components are usable in .mdx files without importing them first.

To add to this list, shadow @nickymeuleman/gatsby-theme-blog/components/mdx-components. Every component that is exported as a named export will be available for use in .mdx under that name, without importing it first.

example declaration of a <Shia /> component

// in src/@nickymeuleman/gatsby-theme-blog/components/mdx-components/index.js
import React from "react"
export * from "@nickymeuleman/gatsby-theme-blog/src/components/mdx-components/index"
const Shia = ({ children }) => (
  <p>Don't let your dreams be dreams! {children}</p>
export { Shia }

example usage in an .mdx file

# Shia LaBeouf says:

  Just do it!
  • Header
  • layout
  • Main

How to shadow components

If you want to use component shadowing, create a file at the following path in your site:


Example usage in MDX

In any MDX blogpost:

import { ComponentName } from "@nickymeuleman/gatsby-theme-blog"

# Lorem Ipsum
<ComponentName />

Components from Gatby-mdx-embed can be used without first importing them

Example usage in React components

In any React component:

import React from "react"
import { ComponentName } from "@nickymeuleman/gatsby-theme-blog"

export default () => (
    <ComponentName />

dev notes