> For AI agents: the complete documentation index is available at https://rspress.rs/llms.txt, the full documentation bundle is available at https://rspress.rs/llms-full.txt.

# Internationalization

To internationalize a Rspress documentation site, complete the following steps:

1. Define I18n text data.
2. Configure the language list, `locales` in `rspress.config.ts`.
3. Configure the default language, `lang` in `rspress.config.ts`.
4. Create docs for each language.
5. Configure sidebar and navbar.
6. Use `useI18n` in custom components.

## Define I18n text data

Create an `i18n.json` file in the current workspace. The directory structure is:

```tree
.
├── docs
├── i18n.json
├── package.json
├── tsconfig.json
└── rspress.config.ts
```

Define the text required for internationalization in this JSON file. Its type is:

```ts
export interface I18n {
  // key: text id
  [key: string]: {
    // key: language
    [key: string]: string;
  };
}
```

For example:

```json title="i18n.json"
{
  "gettingStarted": {
    "en": "Getting Started",
    "zh": "开始"
  },
  "features": {
    "en": "Features",
    "zh": "特性"
  },
  "guide": {
    "en": "Guide",
    "zh": "指南"
  }
}
```

This text data is used in both the **config file** and **custom components**, as explained below.

## Configure `locales`

In `rspress.config.ts`, `locales` configures site-level information such as `lang`, `title`, and `description` for each language.

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  // locales is an array of objects
  locales: [
    {
      lang: 'en',
      // The label in the navbar language switcher
      label: 'English',
      title: 'Rspress',
      description: 'Static Site Generator',
    },
    {
      lang: 'zh',
      label: '简体中文',
      title: 'Rspress',
      description: '静态网站生成器',
    },
  ],
});
```

:::tip Note

`themeConfig.locales` also contains all fields from `locales`, but it will be removed in the future. Use `locales` instead.

:::

For other internationalized theme options, see [API type](https://rspress.rs/api/config/config-theme.md#locales).

## Configure `lang` default language

After configuring `locales`, set the default site language with [lang](https://rspress.rs/api/config/config-basic.md#lang):

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  lang: 'en',
});
```

This is important because **Rspress removes the language prefix from routes in the default language**. For example, `/en/guide/getting-started` becomes `/guide/getting-started`.

## Create docs for each language

After the configuration above, create the following structure in the docs root:

```tree
├── doc
│   ├── en
│   │   ├── _nav.json
│   │   ├── api
│   │   │   └── index.mdx
│   │   ├── guide
│   │   │   ├── _meta.json
│   │   │   └── start
│   │   │       ├── introduction.mdx
│   │   │       └── quick-start.mdx
│   │   └── index.md
│   └── zh
│       ├── _nav.json
│       ├── api
│       │   └── index.mdx
│       ├── guide
│       │   ├── _meta.json
│       │   └── start
│       │       ├── introduction.mdx
│       │       └── quick-start.mdx
│       └── index.md
├── i18n.json
├── package.json
├── rspress.config.ts
└── tsconfig.json

```

Here, docs for different languages live in the `en` and `zh` directories under `docs`, making each language version easy to distinguish.

## Configure \_nav.json and \_meta.json

Use `_nav.json` and `_meta.json` to configure the navbar and sidebar. For details, see [Autogenerated navigation](https://rspress.rs/guide/basic/auto-nav-sidebar.md).

### Navigation bar \_nav.json

In the navbar-level `_nav.json`, `text` can be an i18n key. For example:

```json title="_nav.json"
[
  {
    "text": "guide",
    "link": "/guide/start/introduction"
  },
  {
    "text": "api",
    "link": "/api/"
  }
]
```

Here, `text` is `guide`. Rspress translates this value to `指南` or `Guide` based on `i18n.json` and the current language.

### Sidebar \_meta.json

In the sidebar-level `_meta.json`, `label` can be an i18n key. For example:

```json title="_meta.json"
[
  {
    "type": "dir",
    "name": "start",
    "label": "gettingStarted"
  }
]
```

Here, `label` is `gettingStarted`. Rspress translates this value to `开始` or `Getting Started` based on the current language.

## Use `useI18n` in custom components

When writing MDX or developing a [custom theme](https://rspress.rs/guide/basic/custom-theme.md), custom components may also need localized text. Use `useI18n` to read it:

Rspress provides the [`useI18n`](https://rspress.rs/ui/hooks/use-i18n.md) hook to get the internationalized text, the usage is as follows:

```tsx
import { useI18n } from '@rspress/core/runtime';

const MyComponent = () => {
  const t = useI18n();

  return <div>{t('gettingStarted')}</div>;
};
```

For better type hinting, you can configure `paths` in tsconfig.json:

```json
{
  "compilerOptions": {
    "paths": {
      "i18n": ["./i18n.json"]
    }
  }
}
```

Then use it like this in the component:

```tsx
import { useI18n } from '@rspress/core/runtime';

const MyComponent = () => {
  const t = useI18n<typeof import('i18n')>();

  return <div>{t('gettingStarted')}</div>;
};
```

This way you get type hints for all text keys defined in `i18n.json`.
