Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Change MDX Page URL TO Slugs In Gatsby

The `gatsby-plugin-mdx` creates URLs based off the directory structure of files. This is how to setup Gatsby with an `mdx-pages` directory that lets you put `slug` keys in the frontmatter to control the URL.

### Modules

Code

npm install gatsby-plugin-mdx
npm install gatsby-source-filesystem

### src/layouts/blog-post-v1.js

Code

import { graphql } from 'gatsby';
import { MDXRenderer } from 'gatsby-plugin-mdx';
import React from 'react';

export const query = graphql`
  query($slug: String!) {
    mdx(frontmatter: { slug: { eq: $slug } }) {
      frontmatter {
        title
        slug
      }
      body
    }
  }
`;
const Post = ({ data: { mdx: post } }) => {
  const { title } = post.frontmatter;
  const { body } = post;
  return (
    <div>
        <h1>{title}</h1>
        <MDXRenderer>{body}</MDXRenderer>
    </div>
  );
};
export default Post;

### src/mdx-pages/example-dir/hello-world.mdx

Code

title: Hey, MDX
date: February 15, 2021
slug: /hello-world-example-of-code

This is the `hello-world.mdx` file.

### gatsby-config.js

Code

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `mdx`,
        path: `${__dirname}/src/mdx-pages/`,
      },
    },
    `gatsby-plugin-mdx`,
  ],
}

### gatsby-node.js

Code

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions
  const blogPostV1Layout = require.resolve(`./src/layouts/blog-post-v1.js`)
  const result = await graphql(`
    {
      allMdx {
        edges {
          node {
            frontmatter {
              slug
            }
          }
        }
      }
    }
  `)
  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }
  result.data.allMdx.edges.forEach(({ node }) => {
    createPage({
      path: node.frontmatter.slug,
      component: blogPostV1Layout,
      context: {
        slug: node.frontmatter.slug,
      },
    })
  })
}