How to add MDX and KaTeX to your NextJS app

Back to Blog Home15 January, 2025

Why add MDX and KaTeX to your website?

You most likely found this because you have a blog hosted on your website and are looking for a way to speed up the process of writing posts, but don't want to sacrifice any interactiveness on your website. Additionally, if you're a mathematician like me, you probably also want a way to quickly write math expressions without having to use an entire react component.

This post will show you how to add MDX files as pages on your NextJS website, as well as how to add any MDX plugin (but specifically KaTeX in this tutorial).


How to add MDX to your NextJS app

First, you should have a nextjs project created. I am using NextJS 15 for this project, but any version of NextJS should work fine. I am also using typescript but you can ignore the types if you are using javascript.

npx create-next-app@latest --tsTerminal

Once you have a project, navigate to it's folder and install MDX.

npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdxTerminal

In our case, we will also install the necessary plugins for KaTeX support.

npm install remark-math rehype-katexTerminal

Now that we have all of our packages installed, we must configure NextJS to support MDX files as pages. Additionally, we must specify what plugins we are using. Mind that your next.config.ts file might end with .js or .mjs.

import createMDX from '@next/mdx' /** @type {import('next').NextConfig} */ const nextConfig = { // other config options... pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], } const withMDX = createMDX({ // leave this object empty if you are not using plugins options: { remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex] } }) export default withMDX(nextConfig)next.config.ts

Now we must add a mdx-components.tsx file on the same level as your app folder (page folder if you are using NextJS 12 or below). If you are using a src folder, just create the file in that folder. Non-typescript users will have to end their file with .jsx. Insert the following code,

import type { MDXComponents } from 'mdx/types' export function useMDXComponents(components: MDXComponents): MDXComponents { return { ...components, } } mdx-components.tsx

Since MDX translates to react, you can now simply write your NextJS pages with MDX files.


Importing MDX

You can import any MDX file as a react component by simply using import. For example, you can create a folder on the same level as your app folder and reference MDX files inside with the @/ alias.

import BlogPost from "@/custom-folder/blog-post.mdx"; export default function Page() { return <main> {/* some code here */} <BlogPost /> </main> } page.tsx

Dynamically Importing MDX

First, create a folder where you want to store your MDX pages. I highly recommend that you create a folder on the same level as your app directory so you can reference it with the @/ alias. I named by folder content in my case. In the route where you want dynamic pages, create a [slug] folder with a page.tsx file inside. Insert the following code,

export default async function Page({ params, }: { params: Promise<{ slug: string }> }) { const slug = (await params).slug const { default: Post } = await import(`@/content/${slug}.mdx`) return <Post /> } export const dynamicParams = false export function generateStaticParams() { return [ // list of MDX links (edit this part) { slug: 'first-post' }, { slug: 'second-post' } ] } [slug]/page.tsx

As you can see, I've also statically defined pages in order to optimize prefetching and SEO.