OberonAcademy Logo

OberonAcademy

NextJS MDX

NextJS with MDX

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

next.config.ts

import createMDX from "@next/mdx";

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Configure `pageExtensions` to include markdown and MDX files
  pageExtensions: ["js", "jsx", "md", "mdx", "ts", "tsx"],
  // Optionally, add any other Next.js config below
};

const withMDX = createMDX({
  // Add markdown plugins here, as desired
  extension: /\.(md|mdx)$/,
});

// Merge MDX config with Next.js config
export default withMDX(nextConfig);

src/mdx-components.tsx

import type { MDXComponents } from "mdx/types";

const components: MDXComponents = {};

export function useMDXComponents(): MDXComponents {
  return components;
}

Typography (Optional)

npm install -D @tailwindcss/typography

tailwind.config.js

import typography from "@tailwindcss/typography";

const config = {
  theme: {
    // ...
  },
  plugins: [
    typography,
    // ...
  ],
};

export default config;

src/app/global.css

@plugin "@tailwindcss/typography";

shiki (Optional)

npm install -D shiki

src/components/code.tsx

import { codeToHtml } from "shiki";
import type { BundledLanguage, BundledTheme } from "shiki";

type Props = {
  code: string;
  lang?: BundledLanguage;
  theme?: BundledTheme;
};

export async function Code({
  code,
  lang = "javascript",
  theme = "nord",
}: Props) {
  const html = await codeToHtml(code, {
    lang,
    theme,
  });

  return <div dangerouslySetInnerHTML={{ __html: html }}></div>;
}

src/mdx-components.tsx

import type { MDXComponents } from "mdx/types";
import React from "react";
import { Code } from "./components/code";

const components: MDXComponents = {
  pre: async ({ children }) => {
    const codeElement = React.Children.only(children);
    const lang = codeElement.props.className.split("-")[1];
    return (
      <Code code={codeElement.props.children} lang={lang} theme="github-dark" />
    );
  },
};

export function useMDXComponents(): MDXComponents {
  return components;
}

Links