# i18n (/docs/plugins/i18n)

用于翻译错误信息的国际化插件



i18n 插件允许你根据用户的语言环境翻译 Better Auth 返回的错误信息。它支持多种语言环境检测策略，包括 HTTP 头部、Cookie、会话数据和自定义回调函数。

Better Auth 默认已经提供了英文错误信息，所以你只需要提供其他语言的翻译。

## 安装 [#安装]

<Steps>
  <Step>
    ### 安装插件 [#安装插件]

    <CodeBlockTabs defaultValue="npm" groupId="persist-install">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="npm">
          npm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="pnpm">
          pnpm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="yarn">
          yarn
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="bun">
          bun
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="npm">
        ```bash
        npm install @better-auth/i18n
        ```
      </CodeBlockTab>

      <CodeBlockTab value="pnpm">
        ```bash
        pnpm add @better-auth/i18n
        ```
      </CodeBlockTab>

      <CodeBlockTab value="yarn">
        ```bash
        yarn add @better-auth/i18n
        ```
      </CodeBlockTab>

      <CodeBlockTab value="bun">
        ```bash
        bun add @better-auth/i18n
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Step>

  <Step>
    ### 将插件添加到你的 **auth** 配置中 [#将插件添加到你的-auth-配置中]

    ```ts title="auth.ts"
    import { betterAuth } from "better-auth"
    import { i18n } from "@better-auth/i18n"

    export const auth = betterAuth({
        plugins: [
            i18n({
                translations: {
                    fr: {
                        USER_NOT_FOUND: "Utilisateur non trouvé",
                        INVALID_EMAIL_OR_PASSWORD: "Email ou mot de passe invalide",
                        INVALID_PASSWORD: "Mot de passe invalide",
                    },
                    de: {
                        USER_NOT_FOUND: "Benutzer nicht gefunden",
                        INVALID_EMAIL_OR_PASSWORD: "Ungültige E-Mail oder Passwort",
                        INVALID_PASSWORD: "Ungültiges Passwort",
                    },
                },
            }),
        ],
    })
    ```
  </Step>
</Steps>

## 内置翻译 [#内置翻译]

该软件包附带 22 种语言的现成翻译，因此你无需从头编写翻译。请从 `@better-auth/i18n` 导入 `locales` 以使用它们。

| 代码   | 语言        |
| ---- | --------- |
| `ar` | 阿拉伯语      |
| `bn` | 孟加拉语      |
| `de` | 德语        |
| `en` | 英语        |
| `es` | 西班牙语      |
| `fa` | 波斯语（法尔西语） |
| `fr` | 法语        |
| `hi` | 印地语       |
| `id` | 印度尼西亚语    |
| `it` | 意大利语      |
| `ja` | 日语        |
| `ko` | 韩语        |
| `nl` | 荷兰语       |
| `pl` | 波兰语       |
| `pt` | 葡萄牙语      |
| `ru` | 俄语        |
| `sv` | 瑞典语       |
| `th` | 泰语        |
| `tr` | 土耳其语      |
| `uk` | 乌克兰语      |
| `vi` | 越南语       |
| `zh` | 中文（简体）    |

### 使用所有内置语言环境 [#使用所有内置语言环境]

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import { i18n, locales } from "@better-auth/i18n"

export const auth = betterAuth({
    plugins: [
        i18n({ translations: locales }),
    ],
})
```

### 使用部分语言环境 [#使用部分语言环境]

为了保持软件包精简，你可以只导入所需的语言环境：

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import { i18n, locales } from "@better-auth/i18n"

export const auth = betterAuth({
    plugins: [
        i18n({
            translations: {
                en: locales.en,
                fr: locales.fr,
            },
        }),
    ],
})
```

### 覆盖特定信息 [#覆盖特定信息]

你可以展开一个内置语言环境，只覆盖想要自定义的信息：

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import { i18n, locales } from "@better-auth/i18n"

export const auth = betterAuth({
    plugins: [
        i18n({
            translations: {
                ...locales,
                fr: {
                    ...locales.fr,
                    USER_NOT_FOUND: "Membre introuvable",
                },
            },
        }),
    ],
})
```

### 添加自定义语言环境 [#添加自定义语言环境]

你可以将内置语言环境与自己的自定义语言环境混合使用：

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import { i18n, locales } from "@better-auth/i18n"
import type { TranslationDictionary } from "@better-auth/i18n"

const myLocale: TranslationDictionary = {
    USER_NOT_FOUND: "...",
    INVALID_EMAIL_OR_PASSWORD: "...",
    // ... other error codes
}

export const auth = betterAuth({
    plugins: [
        i18n({
            translations: {
                ...locales,
                xx: myLocale,
            },
        }),
    ],
})
```

## 使用 [#使用]

插件会自动检测用户的语言环境并相应地翻译错误信息。当返回错误时，响应中会同时包含翻译后的信息和原始信息。

### 错误响应格式 [#错误响应格式]

当发生错误且有可用的翻译时，响应内容如下：

```json
{
    "code": "INVALID_EMAIL_OR_PASSWORD",
    "message": "Email ou mot de passe invalide",
    "originalMessage": "Invalid email or password"
}
```

### 语言环境检测 [#语言环境检测]

默认情况下，插件会从 `Accept-Language` HTTP 头部检测语言环境。你可以配置多种检测策略，按照顺序依次检测：

```ts title="auth.ts"
i18n({
    translations: { /* ... */ },
    detection: ["cookie", "header", "session"], // 检测优先级顺序
})
```

可用的检测策略有：

* **`header`** - 使用 `Accept-Language` HTTP 头部（默认）
* **`cookie`** - 从 Cookie 读取语言环境
* **`session`** - 从已认证用户的存储偏好中读取语言环境
* **`callback`** - 使用自定义函数确定语言环境

### 基于 Header 的检测 [#基于-header-的检测]

插件会自动解析 `Accept-Language` 头部，包括质量值：

```http
Accept-Language: fr-CA, fr;q=0.9, en;q=0.8
```

这将依次尝试 `fr-CA`（映射为 `fr`）、`fr`，然后是 `en`。

### 基于 Cookie 的检测 [#基于-cookie-的检测]

要使用基于 Cookie 的检测，请在检测策略中添加 `"cookie"`，并可选配置 Cookie 名称：

```ts title="auth.ts"
i18n({
    translations: { /* ... */ },
    detection: ["cookie", "header"],
    localeCookie: "lang", // 默认为 "locale"
})
```

### 基于会话的检测 [#基于会话的检测]

如果你将用户的语言偏好存储在其资料中，可以通过会话检测：

```ts title="auth.ts"
export const auth = betterAuth({
    user: {
        additionalFields: {
            locale: { type: "string", required: false },
        },
    },
    plugins: [
        i18n({
            translations: { /* ... */ },
            detection: ["session", "header"],
            userLocaleField: "locale", // 默认为 "locale"
        }),
    ],
})
```

### 自定义检测回调 [#自定义检测回调]

对于高级用例，你可以提供自定义语言环境检测函数：

```ts title="auth.ts"
i18n({
    translations: { /* ... */ },
    detection: ["callback", "header"],
    getLocale: (ctx) => {
        // 自定义逻辑：使用查询参数、自定义头部等
        if (!ctx.request) return null;
        const url = new URL(ctx.request.url);
        return url.searchParams.get("lang");
    },
})
```

回调函数会接收完整的端点上下文。应返回语言代码或者 `null`。

## 错误代码 [#错误代码]

插件基于错误代码来翻译错误信息。你可以在 [错误代码参考](/docs/reference/errors) 查找所有可用的错误代码。

常见错误代码包括：

| 代码                             | 默认信息    |
| ------------------------------ | ------- |
| `USER_NOT_FOUND`               | 找不到用户   |
| `INVALID_EMAIL_OR_PASSWORD`    | 邮箱或密码无效 |
| `INVALID_PASSWORD`             | 密码无效    |
| `CREDENTIAL_ACCOUNT_NOT_FOUND` | 找不到凭据账户 |
| `EMAIL_NOT_VERIFIED`           | 邮箱未验证   |
| `SESSION_EXPIRED`              | 会话已过期   |

## 选项 [#选项]

### `translations` [#translations]

**类型：** `Record<string, Record<string, string>>`

**必填：** 是

一个以语言代码为键的翻译字典。每种语言包含错误代码到翻译信息的映射。由于 Better Auth 已经提供英文信息，通常只需提供其他语言的翻译。

```ts
translations: {
    fr: { USER_NOT_FOUND: "Utilisateur non trouvé" },
    de: { USER_NOT_FOUND: "Benutzer nicht gefunden" },
}
```

### `defaultLocale` [#defaultlocale]

**类型：** `string`

**默认值：** `"en"`

当无法检测到语言环境或检测到的语言环境不在翻译字典中时使用的回退语言。

### `detection` [#detection]

**类型：** `Array<"header" | "cookie" | "session" | "callback">`

**默认值：** `["header"]`

语言环境检测策略数组，按优先级顺序排列。第一个返回有效语言的策略将被采用。

### `localeCookie` [#localecookie]

**类型：** `string`

**默认值：** `"locale"`

使用 `"cookie"` 策略时读取的 Cookie 名称。

### `userLocaleField` [#userlocalefield]

**类型：** `string`

**默认值：** `"locale"`

使用 `"session"` 策略时，存储用户语言环境偏好的用户字段名。

### `getLocale` [#getlocale]

**类型：** `(ctx: GenericEndpointContext) => string | null | Promise<string | null>`

使用 `"callback"` 策略时调用的自定义语言环境检测函数。接收完整端点上下文，返回语言代码或 `null`。

<Callout type="info">
  `ctx.request` 对于非 HTTP 调用可能未定义。
</Callout>

## 回退行为 [#回退行为]

* 如果在检测到的语言环境中找不到某个特定错误代码的翻译，则保留内置英文信息。
* 如果检测到的语言环境不在翻译字典中，插件会回退到 `defaultLocale`。
* 如果任何策略都无法检测到语言环境，插件会回退到 `defaultLocale`（默认为 `"en"`）。
* 非错误响应不会被此插件修改。

