A Next.js plugin to configure MDXTS theming, rehype and remark markdown plugins, and the Webpack loader.


First, create the plugin using createMdxtsPlugin and export it along with any other Next.js configuration you need:

import { createMdxtsPlugin } from 'mdxts/next'

const withMdxts = createMdxtsPlugin({
  theme: 'nord',
  gitSource: '',

export default withMdxts({
  // Next.js configuration here...

The plugin enables rendering individual MDX page routes (e.g. about/page.mdx). You can also render a collection of MDX pages using the createSource function in a dynamic route:

import { createSource } from 'mdxts'
import { notFound } from 'next/navigation'

const allDocs = createSource('docs/**/*.mdx')

type Props = { params: { slug: string[] } }

export default async function Page({ params }: Props) {
  const doc = await allDocs.get(params.slug)

  if (!doc) return notFound()

  const { Content } = doc

  return <Content />

Collections also gather a lot of metadata about the MDX files, which can be useful for creating indexes or other dynamic pages like a list of blog posts or a collection of components in a design system.

Files can be included from anywhere. This is especially useful in monorepos for including files that are outside of your Next.js project.

MDX Components

Automated Setup

By default a mdx-components.tsx file is automatically loaded from mdxts/components that overrides pre and code components to use the CodeBlock and CodeInline components respectively.

Manual Setup

You can define custom MDX components and overrides in a top-level mdx-components.tsx file in your project. Either spread the default MDXComponents or import the code and pre components individually from mdxts/components and override the components exactly as you need:

import { MDXComponents } from 'mdxts/components'
import { GeistMono } from 'geist/font/mono'

export function useMDXComponents() {
  return {
    code: (props) => (
      <MDXComponents.code className={GeistMono.className} {...props} />
    pre: (props) => (
          container: GeistMono.className,
          // Clear the default styles
          container: {
            boxShadow: undefined,
            borderRadius: undefined,
  } satisfies MDXComponents

If you need more customization, the CodeBlock component can be fully overridden by importing it from mdxts/components and extending it:

import { CodeBlock as MdxtsCodeBlock, Tokens } from 'mdxts/components'

export function CodeBlock(props: React.ComponentProps<typeof MdxtsCodeBlock>) {
  return (
    <MdxtsCodeBlock {...props}>
      <Tokens />

Then import the CodeBlock component in your mdx-components.tsx file and override the pre component to use it instead of the default CodeBlock component:

import { MDXComponents } from 'mdxts/components'
import { CodeBlock } from './CodeBlock'

export function useMDXComponents() {
  return {
    pre: CodeBlock,
  } satisfies MDXComponents

See the CodeBlock examples section for more ways of customizing the CodeBlock component.

API Reference


View Source

A Next.js plugin to configure MDXTS theming, rehype and remark markdown plugins, and the Webpack loader.

pluginOptions *


theme *

keyof typeof bundledThemes | (string & {})

Path to the VS Code compatible theme used for syntax highlighting the CodeBlock, CodeInline, and Tokens components.



The URL of the production site. This is used for generating sitemap and RSS feed URLs. If using Vercel, the VERCEL_PROJECT_PRODUCTION_URL environment variable will be used by default.



The git source to use for linking to the repository and source files. This is automatically inferred from the git remote URL or Vercel environment variables if not provided.



The branch to use for linking to the repository and source files.



Whether or not to renumber ordered filenames (e.g. 01.getting-started) when adding/removing/modifying MDX files. This only occurs while the development server is running.



Whether or not to add rich highlighted errors in the console when type-checking source code in CodeBlock. Note, this may affect framework error boundaries that don't understand color encoding.

Last updated