Change MDX Page URL TO Slugs In Gatsby

February - 2021

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

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

src/layouts/blog-post-v1.js

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


title: Hey, MDX date: February 15, 2021

slug: /hello-world-example-of-code

This is the hello-world.mdx file.


gatsby-config.js

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

gatsby-node.js

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,
      },
    })
  })
}