---
title: "Internationalisation i18n"
description: "Internationalisation des plugins NocoBase : structure du répertoire locale, écriture des fichiers de traduction, utilisation de this.t / useT / tExpr selon les contextes."
keywords: "i18n,internationalisation,locale,traduction,this.t,useT,tExpr,NocoBase"
---

# Internationalisation i18n

Les plugins NocoBase gèrent les fichiers multilingues via le répertoire `src/locale/`. Une fois les fichiers de traduction écrits, vous pouvez utiliser `this.t()` dans le Plugin, le hook `useT()` dans les composants et `tExpr()` dans les définitions FlowModel pour récupérer le texte traduit.

## Fichiers de traduction

Sous `src/locale/` du plugin, créez un fichier JSON par langue. La clé est le texte source en anglais, la valeur est la traduction dans la langue correspondante :

```bash
my-plugin/
└── src/
    └── locale/
        ├── zh-CN.json
        └── en-US.json
```

```json
// src/locale/zh-CN.json
{
  "Hello": "你好",
  "Save": "保存",
  "Your name is {{name}}": "你的名字是 {{name}}",
  "{{count}} February items": "{{count}} 条记录"
}
```

```json
// src/locale/en-US.json
{
  "Hello": "Hello",
  "Save": "Save",
  "Your name is {{name}}": "Your name is {{name}}",
  "{{count}} February items": "{{count}} items"
}
```

Quelques points à noter :

- **Utilisez le texte anglais comme clé**, ainsi même si une traduction manque, le repli vers l'anglais reste possible
- **Les variables utilisent les doubles accolades** `{{name}}`, conformément à la syntaxe d'[i18next](https://www.i18next.com/translation-function/interpolation)
- **L'ajout initial des fichiers de langue nécessite un redémarrage de l'application** ; les modifications ultérieures sont prises en compte par hot reload
- NocoBase utilise automatiquement le **nom du package** du plugin comme namespace de traduction, les traductions des différents plugins n'entrent donc pas en conflit

## Utilisation dans le Plugin : this.t()

Dans la classe Plugin, `this.t()` **injecte automatiquement le nom du package du plugin courant comme namespace**, vous n'avez pas à passer `ns` manuellement :

```ts
// src/client-v2/plugin.tsx
import { Plugin, Application } from '@nocobase/client-v2';

export class MyPlugin extends Plugin<any, Application> {
  async load() {
    // Utilise automatiquement le nom du package du plugin courant comme ns
    console.log(this.t('Hello')); // -> "你好"

    // Utilise this.t() pour traduire le titre lors de l'enregistrement de la page de configuration
    this.pluginSettingsManager.addMenuItem({
      key: 'my-settings',
      title: this.t('My Settings'),
      icon: 'SettingOutlined',
    });
    this.pluginSettingsManager.addPageTabItem({
      menuKey: 'my-settings',
      key: 'index',
      title: this.t('My Settings'),
      componentLoader: () => import('./pages/MySettingsPage'),
    });
  }
}
```

## Utilisation dans un composant : useT()

Dans un composant React, on ne peut pas utiliser directement `this.t()`. Le squelette de plugin génère automatiquement un fichier `locale.ts` qui fournit le hook `useT()` :

```ts
// src/client-v2/locale.ts (généré automatiquement par le squelette)
import { tExpr as _tExpr, useFlowEngine } from '@nocobase/flow-engine';
// @ts-ignore
import pkg from './../../package.json';

export function useT() {
  const engine = useFlowEngine();
  return (str: string) => engine.context.t(str, { ns: [pkg.name, 'client'] });
}

export function tExpr(key: string) {
  return _tExpr(key, { ns: [pkg.name, 'client'] });
}
```

Utilisation dans un composant :

```tsx
// src/client-v2/pages/MySettingsPage.tsx
import React from 'react';
import { Button } from 'antd';
import { useT } from '../locale';

export default function MySettingsPage() {
  const t = useT();

  return (
    <div>
      <h2>{t('Hello')}</h2>
      <p>{t('Your name is {{name}}', { name: 'NocoBase' })}</p>
      <Button>{t('Save')}</Button>
    </div>
  );
}
```

La fonction `t` renvoyée par `useT()` est déjà liée au namespace du plugin, il suffit de passer la clé.

## Utilisation dans FlowModel : tExpr()

`FlowModel.define()` et `registerFlow()` s'exécutent au chargement du module ; à ce moment, i18n n'est pas encore initialisé et on ne peut pas appeler `t()` directement. Dans ce cas, utilisez `tExpr()` — il génère une chaîne d'expression de traduction différée, résolue à l'exécution :

```tsx
// src/client-v2/models/MyBlockModel.tsx
import { BlockModel } from '@nocobase/client-v2';
import { tExpr } from '../locale';

export class MyBlockModel extends BlockModel {
  renderComponent() {
    return <div>My custom block</div>;
  }
}

// tExpr produit une chaîne du type '{{t("My block")}}', traduite à l'exécution
MyBlockModel.define({
  label: tExpr('My block'),
});

MyBlockModel.registerFlow({
  key: 'flow1',
  title: tExpr('My Block Settings'),
  on: 'beforeRender',
  steps: {
    editTitle: {
      title: tExpr('Edit Title'),
      uiSchema: {
        title: {
          type: 'string',
          title: tExpr('Title'),
          'x-decorator': 'FormItem',
          'x-component': 'Input',
        },
      },
      handler(ctx, params) {
        ctx.model.props.title = params.title;
      },
    },
  },
});
```

En résumé : `this.t()` et `useT()` servent à la traduction au runtime, `tExpr()` à la traduction différée pour les définitions statiques.

:::tip Astuce

`tExpr` a deux origines : le `locale.ts` généré automatiquement par le plugin et `@nocobase/flow-engine`. La différence : le `tExpr` de `locale.ts` est déjà lié au nom du package comme namespace, tandis que le `tExpr` importé directement depuis `@nocobase/flow-engine` n'a pas de namespace. **Dans le code de plugin, utilisez toujours le `tExpr` exporté par `locale.ts`** afin que les traductions correspondent correctement aux fichiers de langue propres au plugin.

:::

## Aide-mémoire des trois usages

| Scénario | Utilisation | Origine |
| --- | --- | --- |
| Dans `load()` du Plugin | `this.t('key')` | Fournie par la classe Plugin |
| Dans un composant React | `const t = useT(); t('key')` | `locale.ts` |
| Définition statique d'un FlowModel | `tExpr('key')` | `locale.ts` |

## Liens connexes

- [Context → Capacités courantes → Internationalisation](../ctx/common-capabilities#internationalisation-ctxt--ctxi18n) — référence API complète pour ctx.t et ctx.i18n
- [Liste des langues](../../languages) — liste complète des codes de langue supportés par NocoBase
- [Développement de composants Component](./index.md) — utilisation de useFlowContext dans les composants
- [Aperçu de FlowEngine](../flow-engine/index.md) — utilisation de tExpr dans FlowModel
