Introduction
Next.js supports mdx as you can see here.
This feature is so useful especially when you want to write a blog post or a documentation page. If you write such a page, you may want to add metadata to it, such as the title, the date, and an abstract.
In this article, I will show you how to export metadata from MDX files and display it on your page using only @next/mdx.
Rendering you first mdx page is very simple and you can do it reading the official documentation.
Metadata
In the official documentation, you can see the section of frontmatter. Frontmatter is a YAML like key/value pairing as the following.
1---2title: Display MDX Metadata on Your Page3date: 2024-04-264---
If you want to use this feature with Next.js, you have to prepare other libraries such as gray-matter or remark-frontmatter. They says,
@next/mdx does not support frontmatter by default,
I prefer to use only @next/mdx because it is the official library.
@next/mdx doen't support frontmatter, but it supports the exporting JavaScript component. In you mdx file, you can export a JavaScript component like this.
post.mdx1export const meta = {2 title: "How to display metadata on your page",3}45# Introduction6Hello world.
How to display metadata on your page
I will use SSG for my website so I use generateStaticParams.
I prepared the following structure
- blogs/[slug]/_posts/*.mdx
- blogs/[slug]/page.tsx
In the page.tsx, write the following code.
page.tsx1import fs from "node:fs";2import path from "node:path";3import { fileURLToPath } from "node:url";45export async function generateStaticParams() {6 const dir = path.dirname(fileURLToPath(import.meta.url));7 const postsDir = path.join(dir, "_posts");8 const filenames = fs.readdirSync(postsDir);910 const mdxFiles = filenames.filter(11 (filename) => path.extname(filename) === ".mdx",12 );1314 return mdxFiles.map((filename) => {15 return {16 params: {17 slug: filename.replace(/\.mdx$/, ""),18 },19 };20 });21}
This function just generates path at build time. In the page component, you can get slug from the params.
page.tsx1export default async function ({2 params: { slug },3}: { params: { slug: string } }) {4 const { meta } = await import(`@/app/blogs/[slug]/_posts/${slug}.mdx`);56 return (7 <div>8 {meta.title}9 </div>10 );11}
Using import(), you can get the metadata from the mdx file.
SSG with AppRouter
Static Export with AppRouter feature have already been supported!