DEV Community

Cover image for Use Custom Paths in Gatsby

Use Custom Paths in Gatsby

Steven Mercatante
Hey, I'm Steven Mercatante and I build things for the web. I'm a full stack software engineer with over 15 years of experience building websites, mobile apps, APIs, CMSs, and ETL pipelines.
Originally published at ・2 min read

This post was originally published at

By default, Gatsby generates URLs for posts from their filename (or the directory name, depending on how you organize your posts). For example, if your post is named, its URL will be

But what if you want to use a different URL (say, use-custom-paths-in-gatsby) without changing the post's filename? That's the problem I ran into. I have a specific naming and organization convention for my posts that should be independent of their URL.

Luckily, we can change how these URLs are generated.

The Solution

First, add a path attribute to the frontmatter for any post whose URL you want to customize. Here's the frontmatter for this post:

title: Use Custom Paths in Gatsby
path: 'use-custom-paths-in-gatsby'

Make sure you restart the Gatsby dev server after adding new fields to frontmatter for the first time, otherwise you won't be able to query them.

You can control how page URLs are generated by overriding the onCreateNode function in gatsby-node.js. Here's what my implementation looks like (yours may differ; the important thing is to see that slug is generated by createFilePath.)

// gatsby-node.js

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions

  if (node.internal.type === 'Mdx') {
    const slug = createFilePath({ node, getNode })
      name: 'slug',
      value: slug,

Remember when we added that path attribute to our post's frontmatter ealier? We're gonna refer to it here. Update your slug definition to use node.frontmatter.path or fallback to the createFilePath invocation.

// gatsby-node.js

exports.onCreateNode = ({ node, getNode, actions }) => {

  if (node.internal.type === "Mdx") {
    let slug = node.frontmatter.path || createFilePath({ node, getNode })

Restart your Gatsby dev server again, and it'll regenerate the slugs. If you added a custom path to any of your posts's frontmatter, you'll now be able to access them via that custom path. In our case, we can now access this post by going to


One of the nice things about having Gatsby autogenerate slugs/paths is that you'll never have two identical URLs for posts since you can't have identically named files or directories. Using this custom method, you need to make sure you don't use the same path for different posts.

👋 Enjoyed this post?

Join my newsletter and follow me on Twitter @mercatante for more content like this.

Discussion (0)