--- title: Internationalization description: Support multiple languages in your documentation --- Fumadocs is not a full-powered i18n library, it manages only its own components and utilities. You can use other libraries like [next-intl](https://github.com/amannn/next-intl) for the rest of your app. Read the [Next.js Docs](https://nextjs.org/docs/app/building-your-application/routing/internationalization) to learn more about implementing I18n in Next.js. ## Manual Setup Define the i18n configurations in a file, we will import it with `@/ilb/i18n` in this guide. ../../examples/i18n/lib/i18n.ts Pass it to the source loader. ```ts title="lib/source.ts" import { i18n } from '@/lib/i18n'; import { loader } from 'fumadocs-core/source'; export const source = loader({ i18n, // [!code highlight] // other options }); ``` And update Fumadocs UI layout options. ```tsx title="app/layout.config.tsx" import { i18n } from '@/lib/i18n'; import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; export function baseOptions(locale: string): BaseLayoutProps { return { i18n, // different props based on `locale` }; } ``` ### Middleware Create a middleware that redirects users to appropriate locale. ```json doc-gen:file { "file": "../../examples/i18n/middleware.ts", "codeblock": { "lang": "ts", "meta": "title=\"middleware.ts\"" } } ``` See [Middleware](/docs/headless/internationalization#middleware) for customisable options. > Note that this is optional, you can also use your own middleware or the one provided by i18n libraries. ### Routing Create a `/app/[lang]` folder, and move all files (e.g. `page.tsx`, `layout.tsx`) from `/app` to the folder. Wrap the root provider inside `I18nProvider`, and provide available languages & translations to it. Note that only English translations are provided by default. ```tsx title="app/[lang]/layout.tsx" import { RootProvider } from 'fumadocs-ui/provider'; import { I18nProvider, type Translations } from 'fumadocs-ui/i18n'; const cn: Partial = { search: 'Translated Content', // other translations }; // available languages that will be displayed on UI // make sure `locale` is consistent with your i18n config const locales = [ { name: 'English', locale: 'en', }, { name: 'Chinese', locale: 'cn', }, ]; export default async function RootLayout({ params, children, }: { params: Promise<{ lang: string }>; children: React.ReactNode; }) { const lang = (await params).lang; return ( {children} ); } ``` ### Pass Locale Pass the locale to Fumadocs in your pages and layouts. ```tsx title="/app/[lang]/(home)/layout.tsx" tab="Home Layout" import type { ReactNode } from 'react'; import { HomeLayout } from 'fumadocs-ui/layouts/home'; import { baseOptions } from '@/app/layout.config'; export default async function Layout({ params, children, }: { params: Promise<{ lang: string }>; children: ReactNode; }) { const { lang } = await params; return {children}; } ``` ```tsx title="/app/[lang]/docs/layout.tsx" tab="Docs Layout" import type { ReactNode } from 'react'; import { source } from '@/lib/source'; import { DocsLayout } from 'fumadocs-ui/layouts/docs'; import { baseOptions } from '@/app/layout.config'; export default async function Layout({ params, children, }: { params: Promise<{ lang: string }>; children: ReactNode; }) { const { lang } = await params; return ( {children} ); } ``` ```ts title="page.tsx" tab="Docs Page" import { source } from '@/lib/source'; export default async function Page({ params, }: { params: Promise<{ lang: string; slug?: string[] }>; }) { const { slug, lang } = await params; // get page source.getPage(slug); // [!code --] source.getPage(slug, lang); // [!code ++] // get pages source.getPages(); // [!code --] source.getPages(lang); // [!code ++] } ``` ### Search Configure i18n on your search solution. - **Built-in Search (Orama):** For [Supported Languages](https://docs.orama.com/open-source/supported-languages#officially-supported-languages), no further changes are needed. Otherwise, additional config is required (e.g. Chinese & Japanese). See [Special Languages](/docs/headless/search/orama#special-languages). - **Cloud Solutions (e.g. Algolia):** They usually have official support for multilingual. ## Writing Documents ../../shared/page-conventions.i18n.mdx ## Navigation Fumadocs only handles navigation for its own layouts (e.g. sidebar). For other places, you can use the `useParams` hook to get the locale from url, and attend it to `href`. ```tsx import Link from 'next/link'; import { useParams } from 'next/navigation'; const { lang } = useParams(); return This is a link; ``` In addition, the [`fumadocs-core/dynamic-link`](/docs/headless/components/link#dynamic-hrefs) component supports dynamic hrefs, you can use it to attend the locale prefix. It is useful for Markdown/MDX content. ```mdx title="content.mdx" import { DynamicLink } from 'fumadocs-core/dynamic-link'; This is a link ```