Internationalization

Learn more implement internationalization in Next Docs UI

Next Docs UI supports I18n routing based on Zeta. Please refer to this guide to setup basic configurations and learn how to structure the documents.

Ensure you have your page tree, layout and middleware ready before getting started.

Create Provider

A I18nProvider is needed for internationalization.

Assume your files are nested under /app/[lang], where the 'lang' parameter is at index 1.

'use client'
 
import { defaultLanguage } from '@/i18n'
import { I18nProvider } from 'next-docs-ui/i18n'
import { useParams, usePathname, useRouter } from 'next/navigation'
import { ReactNode, useCallback } from 'react'
 
export function ClientI18nProvider({ children }: { children: ReactNode }) {
  const router = useRouter()
  const pathname = usePathname()
  const { lang } = useParams() as { lang?: string }
  const onChange = useCallback(
    (v: string) => {
      const segments = pathname.split('/')
 
      segments[1] = v // update parameter
 
      router.push(segments.join('/'))
    },
    [router, pathname]
  )
 
  return (
    <I18nProvider value={{ locale: lang ?? defaultLanguage, onChange }}>
      {children}
    </I18nProvider>
  )
}

Then, wrap the root provider inside of your i18n provider.

<ClientI18nProvider>
  <RootProvider>...</RootProvider>
</ClientI18nProvider>

Adding Translations

We won't translate any content by default, you have to pass it to the Context.

<I18nProvider
  value={{
    text: {
      search: 'Translated Content'
    }
  }}
></I18nProvider>

Add Language Switch

To allow users changing their language, you can put the <LanguageSelect /> component to sidebar same as following:

/[lang]/docs/layout.tsx
import { tree } from '@/source'
import { LanguageSelect } from 'next-docs-ui/i18n'
import { DocsLayout } from 'next-docs-ui/layout'
import { ReactNode } from 'react'
 
export default function Layout({
  params,
  children
}: {
  params: { lang: string }
  children: ReactNode
}) {
  return (
    <DocsLayout
      tree={tree[params.lang] ?? []}
      navTitle="My App"
      sidebarFooter={
        <LanguageSelect
          languages={[
            {
              name: 'English',
              locale: 'en'
            },
            {
              name: 'Chinese',
              locale: 'cn'
            }
          ]}
        />
      }
    >
      {children}
    </DocsLayout>
  )
}

Final Step

Replace all references of original tree with tree[lang] and check if there's any legacy usage.

Static Generation

Generate parameters for every language and page.

export async function generateStaticParams(): Promise<
  { lang: string; slug: string[] }[]
> {
  return languages.flatMap(lang =>
    getPages(lang)!.map(docs => ({
      slug: docs.slug.split('/'),
      lang: lang
    }))
  )
}

Last updated on