React Router
Support i18n routing on your React Router + Fumadocs app.
Setup
Define the i18n configurations in a file, we will import it with @/lib/i18n in this guide.
import { defineI18n } from 'fumadocs-core/i18n';
export const i18n = defineI18n({
defaultLanguage: 'en',
languages: ['cn', 'en'],
});See available options for i18n config.
Routing
Add :lang prefix to all your pages.
import { route, type RouteConfig } from '@react-router/dev/routes';
export default [
route(':lang', 'routes/home.tsx'),
route(':lang/docs/*', 'routes/docs.tsx'),
route('api/search', 'routes/search.ts'),
] satisfies RouteConfig;Make locale optional
You can also use :lang? prefix, and update the i18n config:
import { route, type RouteConfig } from '@react-router/dev/routes';
export default [
route(':lang?', 'routes/home.tsx'),
route(':lang?/docs/*', 'routes/docs.tsx'),
route('api/search', 'routes/search.ts'),
] satisfies RouteConfig;Translations
Define your translations in a file (e.g. lib/layout.shared.tsx), the English translations are used when translations is not specified.
You can also add locale parameter to baseOptions() for localized layout options:
import { i18n } from '@/lib/i18n';
import { defineI18nUI } from 'fumadocs-ui/i18n';
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export const i18nUI = defineI18nUI(i18n, {
translations: {
en: {
displayName: 'English',
},
cn: {
displayName: 'Chinese',
search: '搜尋文檔',
},
},
});
export function baseOptions(locale: string): BaseLayoutProps {
return {
i18n, // required for i18n
// different props based on `locale`
};
}Pages
Pass translations to <RootProvider />:
import { Links, Meta, Scripts, ScrollRestoration, useParams } from 'react-router';
import { RootProvider } from 'fumadocs-ui/provider/react-router';
import { i18nUI } from '@/lib/layout.shared';
import './app.css';
export function Layout({ children }: { children: React.ReactNode }) {
const { lang = i18nUI.defaultLanguage } = useParams();
return (
<html lang="en" suppressHydrationWarning>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body className="flex flex-col min-h-screen">
<RootProvider
i18n={i18nUI.provider(lang)}
>
{children}
</RootProvider>
<ScrollRestoration />
<Scripts />
</body>
</html>
);
}Pass Locale
Pass the locale to Fumadocs in your pages and layouts.
import { i18n } from '@/lib/i18n';
import { loader } from 'fumadocs-core/source';
export const source = loader({
i18n,
// other options
});Search
Configure i18n on your search solution.
- Built-in Search (Orama): See Internationalization.
- Cloud Solutions (e.g. Algolia): They usually have official support for multilingual.
Writing Documents
See i18n routing to learn how to create pages for specific locales.
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.
import { Link, useParams } from 'react-router';
const { lang } = useParams();
<Link to={`/${lang}/about`}>About Us</Link>;In addition, the fumadocs-core/dynamic-link component supports dynamic hrefs, you can use it to attend the locale prefix.
It is useful for Markdown/MDX content.
import { DynamicLink } from 'fumadocs-core/dynamic-link';
<DynamicLink href="/[lang]/another-page">This is a link</DynamicLink>How is this guide?
Last updated on
