Skip to content
Docs
Markdown (MDX)

Markdown (MDX)

Especially for sites where the content varies significantly by locale and may require a different structure, it can be helpful to use Markdown or MDX (opens in a new tab) to provide your localized content. To consume this content in a Next.js app, you can use the @next/mdx (opens in a new tab) package, which allows you to import and render MDX content.

While you can create entire pages using page.mdx files, in an app that uses the [locale] segment, it can be beneficial to import localized MDX content based on the user's locale into a single page.tsx file.

After following the setup instructions for @next/mdx (opens in a new tab), you can consider placing your localized MDX files next to a page that will render them:

src
└── app
    └── [locale]
        ├── page.tsx
        ├── en.mdx
        └── de.mdx

Now, in page.tsx, you can import the MDX content based on the user's locale:

src/app/[locale]/page.tsx
import {notFound} from 'next/navigation';
 
export default async function HomePage({params}) {
  try {
    const Content = (await import(`./${params.locale}.mdx`)).default;
    return <Content />;
  } catch (error) {
    notFound();
  }
}

In this example, an MDX file might look like this:

src/app/[locale]/en.mdx
import Portrait from '@/components/Portrait';
 
# Home
 
Welcome to my site!
 
<Portrait />

Components that invoke hooks from next-intl like useTranslations can naturally be used in MDX content and will respect the user's locale.

Is MDX required to format rich text?

Not at all! The built in message formatting of next-intl supports rich text syntax, which can be used to provide formatting, and to embed React components within messages.

MDX is best suited for cases where content varies significantly by locale. If all you're looking for is rich text formatting, the built-in message formatting may be an easier choice.

Can I load MDX content from a remote source?

Especially if you'd like to allow translators to collaborate on MDX files, you can consider uploading them to a translation management system like Crowdin (opens in a new tab).

In this case, you can fetch the MDX content dynamically from within a page and parse it using a package like next-mdx-remote (opens in a new tab).

Note that MDX compiles to JavaScript and is dynamically evaluated. You should be sure to only load MDX content from a trusted source, otherwise this can lead to arbitrary code execution (opens in a new tab).