---
title: "i18n (Phía server)"
description: "i18n phía server NocoBase: app.i18n, t(), dịch đa ngôn ngữ, cấu hình locales của plugin."
keywords: "i18n,quốc tế hóa,t(),locales,dịch phía server,NocoBase"
---

# i18n

Plugin NocoBase hỗ trợ i18n cho cả phía client và phía server. Bạn có thể triển khai nội dung đa ngôn ngữ trong plugin thông qua một cơ chế thống nhất.

## Quản lý file đa ngôn ngữ

File đa ngôn ngữ của plugin được đặt thống nhất trong thư mục `src/locale`, được đặt tên theo ngôn ngữ, ví dụ:

```bash
|- /plugin-hello
  |- /src
    |- /locale
      |- en-US.json   # Tiếng Anh
      |- zh-CN.json   # Tiếng Trung
```

Mỗi file ngôn ngữ export một object JSON chứa toàn bộ các mục dịch của ngôn ngữ đó, ví dụ:

```json
// zh-CN.json
{
  "Hello": "你好",
  "World": "世界",
  "Enter your name": "请输入你的名字",
  "Your name is {{name}}": "你的名字是 {{name}}"
}
```

```json
// en-US.json
{
  "Hello": "Hello",
  "World": "World",
  "Enter your name": "Enter your name",
  "Your name is {{name}}": "Your name is {{name}}"
}
```

:::tip Mẹo

Khi thêm file ngôn ngữ lần đầu, bạn cần khởi động lại ứng dụng để có hiệu lực. Bạn có thể kiểm tra các mục dịch đã có hiệu lực hay chưa thông qua API:
http://localhost:13000/api/app:getLang?locale=zh-CN

:::

## Instance i18n toàn cục

`app.i18n` là instance i18n toàn cục, phù hợp cho CLI hoặc các tình huống toàn cục của plugin. Bạn có thể kết hợp với inquirer để triển khai tương tác dòng lệnh:

```ts
import select from '@inquirer/select';
import input from '@inquirer/input';

export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.command('test-i18n').action(async () => {
      const answer1 = await select({
        message: 'Select a language',
        choices: [
          { name: '中文', value: 'zh-CN' },
          { name: 'English', value: 'en-US' }
        ]
      });

      await this.app.changeLanguage(answer1);

      const answer2 = await input({
        message: app.i18n.t('Enter your name')
      });

      console.log(app.i18n.t('Your name is {{name}}', { name: answer2 }));
    });
  }
}
```

> `app.i18n.t(text, options)` được dùng để dịch văn bản, hỗ trợ biến template.

## i18n theo Context của request

Mỗi request có `ctx.i18n` là một instance clone của i18n toàn cục, phản hồi thông tin đa ngôn ngữ độc lập theo ngôn ngữ của client.

### Đặt ngôn ngữ phía client

- **Query String**:

```bash
GET /?locale=en-US HTTP/1.1
Host: localhost:13000
```

- **Request Header (khuyến nghị)**:

```bash
GET / HTTP/1.1
Host: localhost:13000
X-Locale: en-US
```

### Sử dụng trong middleware

```ts
export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.use(async (ctx, next) => {
      if (ctx.path === '/api/test-i18n') {
        ctx.body = ctx.t('Hello', { ns: '@my-project/plugin-hello' });
      }
      await next();
    });
  }
}
```

Truy cập http://localhost:13000/api/test-i18n?locale=zh-CN sẽ trả về `你好`.

## i18n nội bộ của plugin

Trong plugin, bạn có thể dùng trực tiếp `plugin.t(key, options)` để lấy bản dịch:

```ts
export class PluginSampleI18nServer extends Plugin {
  load() {
    this.app.use(async (ctx, next) => {
      if (ctx.path === '/api/plugin-i18n') {
        ctx.body = this.plugin.t('Hello');
      }
      await next();
    });
  }
}
```

> `plugin.t(text)` tương đương với `ctx.t(text, { ns })`

## Liên kết liên quan

- [i18n phía client](../client/component/i18n.md) — Cách viết file dịch phía client, cách dùng useT, tExpr
- [Danh sách ngôn ngữ](../languages.md) — Danh sách đầy đủ mã ngôn ngữ NocoBase hỗ trợ
