Internationalization

Support multiple languages in your documentation

Next Docs has built-in support for internationalized routing in Contentlayer. You can define a list of supported languages and pass it to i18n utilities. Read the Next.js Docs to learn more about implementing I18n in Next.js.

Setup

  1. Put all supported languages in a file.
i18n.ts
export const defaultLanguage = 'en'
export const languages = ['en', 'cn']
  1. Change your current configurations.
source.ts
import { allDocs, allMeta } from 'contentlayer/generated'
import { createContentlayer } from 'next-docs-zeta/contentlayer'
import { languages } from './i18n'
 
export const { getPage, getPageUrl, tree } = createContentlayer(
  allMeta,
  allDocs,
  { languages }
)
  1. Create i18n middleware.
middleware.ts
import { defaultLanguage, languages } from '@/i18n'
import { createI18nMiddleware } from 'next-docs-zeta/middleware'
import { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  return createI18nMiddleware(
    request,
    languages,
    defaultLanguage,
    (locale, slug) => `/${locale}/docs/${slug}` // the format of redirected url
  )
}
 
export const config = {
  // Matcher ignoring `/_next/` and `/api/`
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)']
}
  1. Create a dynamic route, ensure all special files are nested under /app/[lang].
/app/[lang]/layout.tsx
export default function Layout({ params }: { params: { lang: string } }) {
  return (
    <html lang={params.lang}>
      <body>{children}</body>
    </html>
  )
}

Get Pages

To get the pages with specific languages, use the utilities exported from source.ts.

import { getPage, getPages, tree } from '@/source'
 
// get page tree
const t = tree[params.lang]
 
// get page
const page = getPage(params.slug, params.lang)
 
// get pages
const pages = getPages(params.lang)

You will need some extra configurations in order to implement international document searching.

The default createSearchAPI doesn't provide functionality for i18n. Instead, you can use createI18nSearchAPI.

  1. Update the route handler.
/api/search/route.ts
import { languages } from '@/i18n'
import { getPages, getPageUrl } from '@/source'
import { createI18nSearchAPI } from 'next-docs-zeta/server'
 
export const { GET } = createI18nSearchAPI('simple', {
  indexes: languages.map(lang => {
    const pages = getPages(lang)!.map(page => ({
      title: page.title,
      content: page.body.raw,
      url: getPageUrl(page.slug, lang)
    }))
 
    return [lang, pages]
  })
})
  1. Add locale to search dialog, this will only allow pages with specified locale to being searched by the user.
function Dialog() {
  const { search, setSearch, query } = useDocsSearch(locale)
 
  //...
}

Pages Structure

You can create a page by adding .{locale} to your MDX file name. Pages can't be language-specific unless you have created the same page for default locale.

For meta files, you can add -{locale} to the file name instead (meta-cn.json).

If it's the default language, just leave it empty like get-started.mdx. Do not use add locale code to file name.

Example

Assume your default language is en.

Name
meta.jsonAllowed
meta-cn.jsonAllowed
meta-en.jsonNot Allowed
get-started.mdxAllowed
get-started.cn.mdxAllowed
get-started.en.mdxNot Allowed
components.cn.mdxNot Allowed

Last updated on