Using Frontmatter in MDX with Next.js
Showcasing how to use frontmatter in MDX files to store metadata and how to access that metadata in your Next.js components.
// pages/posts/[slug].tsx
import { serialize } from 'next-mdx-remote/serialize'
import { MDXRemote } from 'next-mdx-remote'
import { GetStaticPaths, GetStaticProps } from 'next'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
export default function Post({ source, frontMatter }) {
// Render the MDX content with the metadata
return (
<article>
<h1>{frontMatter.title}</h1>
<p>{frontMatter.date}</p>
<MDXRemote {...source} />
</article>
)
}
export const getStaticPaths: GetStaticPaths = async () => {
// Get all .mdx files in the posts directory
const paths = fs.readdirSync(path.join(process.cwd(), 'posts'))
.filter(path => path.endsWith('.mdx'))
.map(path => ({ params: { slug: path.replace(/\.mdx$/, '') }}))
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const slug = params?.slug
const filePath = path.join(process.cwd(), 'posts', `${slug}.mdx`)
const source = fs.readFileSync(filePath)
// Use gray-matter to parse the post metadata section
const { content, data } = matter(source)
// Use next-mdx-remote to serialize the MDX content
const mdxSource = await serialize(content)
return { props: { source: mdxSource, frontMatter: data } }
}
This TypeScript code for Next.js defines a dynamic route for MDX blog posts and uses `gray-matter` to parse frontmatter metadata. It serializes the MDX content with `next-mdx-remote` to make it ready for rendering and passes both serialized content and frontmatter metadata to the `Post` component to be rendered as a blog post.
// posts/example.mdx
---
title: 'Hello, world!'
date: 'January 1, 2021'
---
# This is a title
Hello, world content...
This is an example of an MDX file with frontmatter. It contains metadata (title and date) at the top, delimited by `---`, followed by the MDX content. This file would be placed in the `posts` directory of your Next.js project.