Migrate to Netlify Today

Netlify announces the next evolution of Gatsby Cloud. Learn more

Adding MDX Pages

Examples

  • Using MDX

Introduction

MDX is Markdown for the component era. It lets you write JSX embedded inside Markdown. This combination allows you to use Markdown’s terse syntax (such as # Heading) for your content and JSX for more advanced or reusable components.

This is useful in content-driven sites where you want the ability to introduce components like charts or alerts without having to configure a plugin. MDX also shines in interactive blog posts, documenting design systems, or long form articles with immersive or dynamic interactions.

Prerequisites

  • A Gatsby project set up with gatsby@4.21.0 or later.

Installation and configuration

If you already have a Gatsby site that you’d like to add MDX to, you can follow these steps for configuring the gatsby-plugin-mdx plugin.

Starting a new project? Skip the setup and create a new project using npm init gatsby

Choose the option “Add Markdown and MDX support” to add the necessary MDX dependencies.

Already using Remark? Check out the How-To Guide on Migrating from Remark to MDX.

  1. Install the required dependencies:

  2. Update your gatsby-config.js to use gatsby-plugin-mdx and gatsby-source-filesystem

  3. Restart your local development server by running gatsby develop.

Writing pages in MDX

After installing gatsby-plugin-mdx, MDX files located in the src/pages directory will automatically be turned into pages.

gatsby-plugin-mdx looks for MDX files and automatically transpiles them so that Gatsby can render them. Make sure to parse these MDX files with gatsby-source-filesystem, otherwise they can’t be located.

Pages are rendered at a URL that is constructed from the filesystem path inside src/pages. For example, an MDX file at src/pages/awesome.mdx will result in a page being rendered at yoursite.com/awesome.

Create a new .mdx file in the src/pages directory (e.g. src/pages/chart-info.mdx). You can use Markdown syntax to add different HTML elements.

Using frontmatter in MDX

By default, gatsby-plugin-mdx supports frontmatter so you can define things like titles and paths to use in your GraphQL queries. You can declare frontmatter at the beginning of your MDX document:

You can then query for this frontmatter data with GraphQL:

Frontmatter is also available in props.pageContext.frontmatter and can be accessed in blocks of JSX in your MDX document:

Importing JSX components into MDX documents

MDX allows you to use React components alongside Markdown. You can import components from third-party libraries (like theme-ui) to take advantage of pre-built functionality like data visualizations, email signup forms, or call-to-action buttons. You can also import and reuse your own React components and even other MDX documents.

To import a component, add a JavaScript import statement to your MDX file. Once you’ve imported a component, you can use it in the body of your MDX file the same way you’d normally use a React component:

Note: If you would like to include frontmatter metadata and import components, the frontmatter needs to appear at the top of the file and then imports can follow.

Importing MDX files into JSX components

You can also import MDX files into JSX components. For example, if you have a MDX file inside src/content that you want to include into a React component, you’ll first need to make sure that gatsby-plugin-mdx can transpile that file. For this you have to point gatsby-source-filesytem to this folder:

Afterwards you’ll be able to use the MDX file (the .mdx file extension in the import is necessary) like so:

Defining a layout

You can use regular layout components to apply layout to your sub pages.

To inject them, you have several options:

  1. Use the wrapPageElement API including its SSR counterpart.
  2. Add an export default Layout statement to your MDX file, see MDX documentation on Layout.
  3. When using the createPage action to programatically create pages, you should use the following URI pattern for your page component: your-layout-component.js?__contentFilePath=absolute-path-to-your-mdx-file.mdx. To learn more about this, head to the programmatically creating pages section just below.

Make components available globally as shortcodes

To avoid having to import the same component inside of every MDX document you author, you can add components to an MDXProvider to make them globally available in MDX pages. This pattern is sometimes referred to as shortcodes.

All MDX components passed into the components prop of the MDXProvider will be made available to MDX documents that are nested under the provider. You have multiple options on how to use this layout component in your site. Learn more in the layout section of the gatsby-plugin-mdx README.

Now, you can include components in your MDX without importing them:

Because the <Message /> and <Chart /> components were passed into the provider, they are available for use in all MDX documents.

Programmatically creating pages

Sometimes you want to be able to programmatically create pages using MDX content that lives at arbitrary locations outside of src/pages or in a remote CMS.

For instance, let’s say you have a Gatsby website, and you want to add support for MDX so you can start your blog. The posts will live in content/posts. You can do this with the help of gatsby-source-filesystem and createPages in gatsby-node.js.

Source MDX pages from the filesystem

You’ll need to use gatsby-source-filesystem and tell it to source “posts” from a folder called content/posts located in the project’s root.

You can read about gatsby-source-filesystem if you’d like to learn more.

Add MDX files

Before you can write any GraphQL queries and programmatically create pages, you need to add some content.

Make a folder called content/posts and create two files in it called blog-1.mdx and blog-2.mdx. You can do this on the command line in a terminal by using the following commands from the root of your project.

Note: mkdir -p path/to/a/directory will create every folder in the path if it does not exist.

touch <filename> will create an empty file named <filename>. The brackets ({}) are an expansion which means you can create multiple files in one command.

Open up each of the files you just created and add some content.

Create pages from sourced MDX files

In order to create pages from the sourced MDX files, you need to construct a query that finds all MDX nodes and pulls out the slug field from the frontmatter you defined.

Note: You can open up a GraphiQL console for query testing in your browser at http://localhost:8000/___graphql

For further reading, check out the createPages API.

Make a layout template for your posts

You can create a file called post.jsx in src/templates - this component will be rendered as the template for every post. Now, create a component that accepts your compiled MDX content via children and uses GraphQL data to show the title:

Now you need to tell gatsby-plugin-mdx to use your PageTemplate component as layout for your post. To do this, you need to change the structure of the component URI in your createPage call:

From an absolute path to your component (e.g. /absolute/path/to/layout-component.js) to a path that contains a query parameter __contentFilePath (e.g. /absolute/path/to/layout-component.js?__contentFilePath=/absolute/path/to/content.mdx).

Please note: While you can create your layout templates as TypeScript files (e.g. post.tsx) you can’t actually use most TypeScript syntax. This is because the underlying acorn parser only understands modern JS and JSX syntax.

However, you can import your TypeScript types from another file instead. In most cases this should then work — if you’re still encountering an “Unexpected token” error, try removing TypeScript syntax piece by piece to see why it breaks.

Change your gatsby-node.js as following:

That’s it, you’re done. Run gatsby develop to see your posts wrapped with post.jsx.

Adding additional fields to your GraphQL MDX nodes

To extend your GraphQL nodes, you can use the onCreateNode API.

You can find examples in the README of gatsby-plugin-mdx.

gatsby-remark-* and remark plugins

gatsby-plugin-mdx can also use gatsby-remark-* (e.g. gatsby-remark-images) and remark (e.g. remark-gfm) plugins. You can learn more about this in the configuration section of gatsby-plugin-mdx’s README.

Additional Resources

Start building today on Netlify!
Edit this page on GitHub
© 2023 Gatsby, Inc.