Blog>
Snippets

Creating MDX Pages

Demonstrate how to create new MDX pages in a Next.js 14 project, including how to export metadata and render components within the MDX files.
import { MDXProvider } from '@mdx-js/react';
import Head from 'next/head';
import Image from 'next/image';
import Link from 'next/link';

const components = {
  img: Image,
  a: Link,
  // You can add other custom components here
};

export default function MDXLayout({ children, frontMatter }) {
  return (
    <>
      <Head>
        <title>{frontMatter.title}</title>
        <meta name="description" content={frontMatter.description} />
      </Head>
      <MDXProvider components={components}>{children}</MDXProvider>
    </>
  );
}
This is a standard layout component for MDX pages in a Next.js project. It imports the necessary components from Next.js and MDX libraries. It creates a custom `components` object for rendering certain Markdown elements as Next.js components. The layout accepts `children` as the MDX content and `frontMatter` for meta data like title and description, which it uses to fill in the HEAD of the document.
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { serialize } from 'next-mdx-remote/serialize';
import MDXLayout from './MDXLayout';

export async function getStaticProps({ params }) {
  const postFilePath = path.join(process.cwd(), 'content', `${params.slug}.mdx`);
  const source = fs.readFileSync(postFilePath);
  const { content, data } = matter(source);
  const mdxSource = await serialize(content);

  return { props: { source: mdxSource, frontMatter: data } };
}

// Define the paths for static generation
export async function getStaticPaths() {
  // List all .mdx files in the content directory
  const postsDirectory = path.join(process.cwd(), 'content');
  const filenames = fs.readdirSync(postsDirectory);

  const paths = filenames.map(name => ({
    params: {
      slug: name.replace(/\.mdx$/, ''),
    },
  }));

  return { paths, fallback: false };
}

// Render the MDX content using the custom MDXLayout
function PostPage({ source, frontMatter }) {
  return <MDXLayout frontMatter={frontMatter}>{source}</MDXLayout>;
}

export default PostPage;
This code is responsible for fetching and displaying MDX pages in a Next.js app. It uses the `getStaticProps` function to read an MDX file's content and metadata using the `gray-matter` library, and `serialize` from `next-mdx-remote` to parse the content. `getStaticPaths` is set up to determine the paths to be statically generated at build time. The `PostPage` function component renders the content using `MDXLayout`. Replace `./MDXLayout` with the correct path to where your layout is actually located.
import '../styles/globals.css';

// This imports a global CSS file. Place your global styles here.
This is an import statement typically found in the `pages/_app.js` or `pages/_app.tsx` file to include global CSS styles in a Next.js app. Whenever you have styles that should apply across your entire app, you put them into this global stylesheet.
/* Add this CSS to your styles/globals.css file */

body {
  font-family: 'Arial', sans-serif;
}

a {
  color: #0070f3;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}
This is a CSS snippet that can be added to a global stylesheet in the Next.js project, setting basic styles for the body font and anchor tags. It will affect the appearance across all MDX pages.