Localization

Pre-release
Ship documentation in multiple languages from a single source
View as Markdown

Fern lets you publish your documentation in multiple languages from a single set of source files. Readers switch languages from a dropdown in the header, search is scoped to the active language, and each locale has its own URL so search engines can index it separately.

You maintain your default-language pages as usual. When you run fern generate --docs, Fern auto-translates them into every configured language as part of the build, so your site rebuilds with up-to-date translations each time.

See it live on the i18n example site (source).

Localization is under active development. Automated translation, Ask Fern, fern check errors, and API Reference pages are still in progress.

Reach out if you’re interested in implementing localization for your docs.

Early access setup

The manual setup below works today. Once localization is generally available, most of these steps will be handled for you.

1

Upgrade the Fern CLI

Localization requires the latest CLI version.

$fern upgrade
2

Declare languages in docs.yml

Add a translations key to your docs.yml listing each supported language. Mark one language as the default.

docs.yml
1translations:
2 - lang: en
3 default: true
4 - lang: ja
5 - lang: zh

Fern supports both two-letter ISO 639-1 codes (e.g., en, ja, zh) and full BCP 47 locale tags (e.g., ja-JP, pt-BR, zh-Hans-CN).

3

Add a translations folder

Create a translations folder inside your fern directory. Each language declared in docs.yml needs a subfolder matching its locale code. This folder contains your translated content and navigation overrides.

fern
fern.config.json
docs.yml
products
docs
translations
ja
fern
docs.yml
products
products
4

Translate your navigation

For each base config YAML you have — docs.yml, product files, version files — create a matching file under fern/translations/{locale}/ at the same relative path and mirror its structure.

Within an entry, include only the fields you want to translate (display-name, subtitle, section, page); anything you omit falls back to the base file. Add a slug: to pin the base URL when the page name is an English term like markdown or api-catalog. Example PR

fern/translations/ja/fern/docs.yml
1products:
2 - display-name: ホーム
3 path: ./products/home/home.yml
4 subtitle: 開発者体験を向上させる製品
5
6 - slug: sdks
7 display-name: SDK
8 path: ./products/sdks/sdks.yml
9 subtitle: 複数の言語でクライアントライブラリを生成
10
11 - slug: docs
12 display-name: ドキュメント
13 path: ./products/docs/docs.yml
14 subtitle: 美しいインタラクティブなドキュメントサイトを生成

Field-level fallback only applies within an entry. If a page is in the base nav but missing from the localized YAML, the localized URL serves the default-language page — even when a translated .mdx exists. Register every page you translate here too.

5

Translate page content

Place translated .mdx files in fern/translations/{locale}/products/ mirroring the original file structure. Use the sidebar-title frontmatter field to override the sidebar entry per language:

fern/translations/ja/products/docs/pages/getting-started/overview.mdx
1---
2sidebar-title: 概要
3---
4
5Fernドキュメントへようこそ。

You only need to translate the files you want to localize. Any page that’s registered in the localized navigation but has no matching .mdx falls back to the default-language file automatically.

Adding a translated .mdx alone isn’t enough to localize a page — the page must also have an entry in the localized navigation YAML. Without a localized nav entry, the page falls back to the default language even when a translation file exists.

6

Generate your docs

$fern generate --docs

Fern picks up the translations, renders the language switcher in the header, and emits a sitemap entry per locale. You can also preview translations locally with fern docs dev.