logologo
Get Started
Guide
Development
Plugins
API
English
简体中文
Get Started
Guide
Development
Plugins
API
English
简体中文
logologo

Quick Start

Plugin Development Overview
Write Your First Plugin
Project Structure

Server Development

Overview
Plugin
Collections
Database
DataSourceManager
ResourceManager
ACL
Middleware
Cache
Event
Context
Migration
Logger
I18n
Command
CronJobManager
Test

Client Development

Overview
Plugin
Context
Router
ACL
DataSourceManager
Resource
Request
Styles & Themes
Logger
I18n
Test

Others

Plugin Upgrade Guide
Languages
Dependency Management
Build
Previous PageLogger
Next PageCommand

#I18n

NocoBase plugins support multi-language internationalization (i18n) for both frontend and backend. Through a unified mechanism, you can easily implement multi-language content in plugins.

#Multi-language File Management

Plugin multi-language files are uniformly stored in the src/locale directory. It's recommended to name them by language file, for example:

|- /plugin-hello
  |- /src
    |- /locale
      |- en-US.json   # English language
      |- zh-CN.json   # Chinese language

Each language file exports a JSON object containing all translation entries for that language, for example:

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

When adding language files for the first time, you need to restart the application for them to take effect. You can verify translation entries through the API:
http://localhost:13000/api/app:getLang?locale=zh-CN

#Global i18n Instance

app.i18n is the global i18n instance, suitable for CLI or plugin global scenarios. Can be combined with inquirer to implement command-line interactions:

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) is used to translate text and supports template variables.

#Request Context i18n

Each request's ctx.i18n is a clone of the global i18n instance, responding independently with multilingual information based on the client's language.

Set Client Language

  • Query String:
GET /?locale=en-US HTTP/1.1
Host: localhost:13000
  • Request Header (Recommended):
GET / HTTP/1.1
Host: localhost:13000
X-Locale: en-US

Use in Middleware

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();
    });
  }
}

Accessing http://localhost:13000/api/test-i18n?locale=zh-CN will return 你好 (the Chinese for "Hello").

#Plugin Internal i18n

Plugins can directly use plugin.t(key, options) to get translations:

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) is equivalent to ctx.t(text, { ns })

#Related APIs

  • app.i18n
  • app.t(text, options)
  • ctx.i18n
  • ctx.t(text, options)
  • plugin.t()
  • tExpr(text, options)