hrtyy.dev

Display MDX Metadata on Your Next.js Page

export metadata from MDX files and display it on your page using only @next/mdx

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 Page
3date: 2024-04-26
4---

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.mdx
1export const meta = {
2 title: "How to display metadata on your page",
3}
4
5# Introduction
6Hello 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.tsx
1import fs from "node:fs";
2import path from "node:path";
3import { fileURLToPath } from "node:url";
4
5export 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);
9
10 const mdxFiles = filenames.filter(
11 (filename) => path.extname(filename) === ".mdx",
12 );
13
14 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.tsx
1export default async function ({
2 params: { slug },
3}: { params: { slug: string } }) {
4 const { meta } = await import(`@/app/blogs/[slug]/_posts/${slug}.mdx`);
5
6 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!