Fumadocs

Internationalization

Support multiple languages in your documentation

Read the Next.js Docs to learn more about implementing I18n in Next.js.

Setup

Define all supported languages in a file.

i18n.ts
export const defaultLanguage = 'en';
export const languages = ['en', 'cn'];

Change your current source configurations.

source.ts
import { languages } from '@/i18n';
import { loader } from 'fumadocs-core/source';
 
export const { getPage, getPages, pageTree } = loader({
  languages,
  ...
});

Create the middleware that redirects users when missing locale.

middleware.ts
import { defaultLanguage, languages } from '@/i18n';
import { createI18nMiddleware } from 'fumadocs-core/middleware';
 
export default createI18nMiddleware({
  languages,
  defaultLanguage,
});
 
export const config = {
  // Matcher ignoring `/_next/` and `/api/`
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};

Create a dynamic route /app/[lang], and move all special files to the folder.

A I18nProvider is needed for localization. Wrap the root provider inside your I18n provider.

import { RootProvider } from 'fumadocs-ui/provider';
import { I18nProvider } from 'fumadocs-ui/i18n';
 
export default function RootLayout({
  params,
  children,
}: {
  params: { lang: string };
  children: React.ReactNode;
}) {
  return (
    <html lang={params.lang}>
      <body>
        <I18nProvider locale={params.lang}>
          <RootProvider>{children}</RootProvider>
        </I18nProvider>
      </body>
    </html>
  );
}

Writing Documents

see Page Conventions to learn how to organize your documents.

Configure i18n on your search solution. For Flexsearch, see Setup I18n.

Get Pages

To get the pages of a specific language, use the utilities exported from source.ts.

import { getPage, getPages, pageTree } from '@/app/source';
 
// get page tree
pageTree[params.lang];
 
// get page
getPage(params.slug, params.lang);
 
// get pages
getPages(params.lang);

Static Generation

Generate parameters for every language and page.

import { getPages } from '@/app/source';
import { languages } from '@/i18n';
 
export async function generateStaticParams() {
  return languages.flatMap((lang) =>
    getPages(lang)!.map((page) => ({
      slug: page.slug,
      lang,
    })),
  );
}

Middleware Options

You can also customise the I18n middleware.

Hide Locale Prefix

To hide the locale prefix, for example, use / instead of /en where en is the default locale, use the hidePrefix option.

ModeDescription
alwaysAlways hide the prefix
default-localeOnly hide the default locale
neverNever hide the prefix (default)

It uses NextResponse.rewrite under the hood.

import { defaultLanguage, languages } from '@/i18n';
import { createI18nMiddleware } from 'fumadocs-core/middleware';
 
export default createI18nMiddleware({
  languages,
  defaultLanguage,
  hideLocale: 'default-locale',
});

Adding Translations

We only provide english translation by default, you have to pass your translations to the provider.

import { I18nProvider } from 'fumadocs-ui/i18n';
 
<I18nProvider
  translations={{
    cn: {
      name: 'Chinese', // required
      search: 'Translated Content',
    },
  }}
>
  ...
</I18nProvider>;

Add Language Switch

To allow users changing their language, enable i18n on docs layout.

[lang]/docs/layout.tsx
import { DocsLayout } from 'fumadocs-ui/layout';
 
export default function Layout({ children }: { children: React.ReactNode }) {
  return <DocsLayout i18n>{children}</DocsLayout>;
}

Last updated on

On this page

Edit on Github