Skip to main content
Version: 0.1.x

Introduction​

LinaPro internationalization is loaded and merged by the core framework. The core framework provides base language packs, source plugins provide their own language packs, and dynamic plugin release artifacts can carry language resources. After a plugin is enabled, the core framework merges all available resources into the runtime locale directory for the admin workspace, menus, error messages, plugin pages, and API documentation.

The main repository currently provides two locale resource sets by default: zh-CN and en-US. Other languages must be created and maintained by the project team.

Configuration​

Internationalization is configured in config.yaml:

i18n:
default: zh-CN
enabled: true
locales:
- locale: en-US
nativeName: English
- locale: zh-CN
nativeName: įŽ€äŊ“中文
OptionDescription
defaultDefault locale used when a request does not include a locale identifier or requests an unsupported locale
enabledWhether multilingual support is enabled; when disabled, the frontend hides the language switcher
localesRuntime list of selectable locales and display names

locales affects both the frontend language switcher and the set of language resources that should be fully maintained at runtime.

Resource Layout​

Core framework language resources live under:

apps/lina-core/manifest/i18n/<locale>/

A typical structure looks like this:

manifest/i18n/
├── zh-CN/
│ ├── framework.json
│ ├── menu.json
│ ├── dict.json
│ ├── config.json
│ ├── error.json
│ ├── job.json
│ ├── notify.json
│ ├── role.json
│ ├── plugin.json
│ ├── public-frontend.json
│ └── apidoc/
│ ├── common.json
│ └── core-api-*.json
└── en-US/
└── ...

JSON files directly under <locale>/ provide runtime UI copy, while JSON files under apidoc/ provide API documentation translations. The two resource types are loaded separately so API documentation resources do not pollute runtime UI copy.

Language Pack Format​

Language packs use JSON. They may use nested structures or flat dot-separated keys:

{
"menu": {
"dashboard": {
"title": "Dashboard"
}
},
"framework": {
"description": "An AI-native full-stack framework for sustainable delivery"
}
}

Equivalent flat-key form:

{
"menu.dashboard.title": "Dashboard",
"framework.description": "An AI-native full-stack framework for sustainable delivery"
}

After loading, the runtime normalizes resources into flat keys. To reduce collisions, plugin language packs should stay under the plugin's own namespace.

Plugin Internationalization​

Source plugins maintain language packs in their own manifest/i18n/ directories:

apps/lina-plugins/content-notice/manifest/i18n/
├── zh-CN/
│ ├── content-notice.json
│ └── apidoc/
│ └── plugin-api-notice.json
└── en-US/
└── content-notice.json

Plugin language packs should use a plugins.<plugin-id>. namespace:

{
"plugins": {
"content-notice": {
"notice": {
"title": "Notices",
"status": {
"draft": "Draft",
"published": "Published"
}
}
}
}
}

Dynamic plugin language resources are shipped with the release artifact. When the core framework loads a valid release version, those resources are merged as plugin resources; when the plugin is disabled or upgraded, they change along with the runtime snapshot.

API Documentation Translation​

API documentation translations live under manifest/i18n/<locale>/apidoc/. Both the core framework and plugins can maintain their own apidoc resources:

manifest/i18n/zh-CN/apidoc/core-api-auth.json
manifest/i18n/zh-CN/apidoc/common.json
manifest/i18n/zh-CN/apidoc/plugin-api-notice.json

API documentation translations use structured keys. Display text should not be used as keys. Plugin translations should only maintain their own plugin namespace, while core framework translations should only maintain core API namespaces.

en-US API documentation resources can usually remain as empty placeholders, allowing English summary, dc, and field descriptions in source code to serve as the default copy. Chinese and other non-English languages should provide complete translations so the admin workspace Developer Center stays readable.

Locale Selection​

Runtime locale selection usually comes from request headers, query parameters, or user preferences stored by the frontend. The exact call path is coordinated by the admin workspace and core framework middleware. If the requested locale does not exist or is not configured, the core framework falls back to i18n.default.

When i18n.enabled: false, the frontend hides the language switcher, while the core framework still loads the required copy using the default locale.

Adding a New Language​

Adding a new language usually requires four steps:

  1. Add the language code and native display name to i18n.locales in config.yaml.
  2. Create core framework language packs under apps/lina-core/manifest/i18n/<locale>/.
  3. Add language packs under manifest/i18n/<locale>/ for every enabled plugin.
  4. If API documentation localization is required, add resources under manifest/i18n/<locale>/apidoc/.

Example:

i18n:
locales:
- locale: ja-JP
nativeName: æ—ĨæœŦčĒž

Create the directory:

mkdir -p apps/lina-core/manifest/i18n/ja-JP/apidoc

LinaPro does not automatically generate translation content for newly added languages. Missing translations fall back to default copy or display untranslated keys, depending on the call site.

Cache and Refresh​

Runtime language resources are cached. In development, restarting the service is the most direct way to pick up language pack changes:

make dev

In production, use runtime cache invalidation and refresh the smallest necessary scope:

ScopeDescription
Specific localeRefresh only one locale
Specific pluginRefresh only one plugin's language resources
Core framework resourcesRefresh only core framework language packs
API documentation resourcesRefresh only the apidoc translation directory

Avoid clearing all language and plugin caches without a reason. A full refresh can cause brief translation jitter and increases load cost on the next request.

Language Codes​

LinaPro uses standard IETF BCP 47 language codes. Common examples:

LanguageCode
Simplified Chinesezh-CN
Traditional Chinesezh-TW
Englishen-US
Japaneseja-JP
Koreanko-KR

Directory names, locale fields in config.yaml, and frontend request locale parameters should stay consistent.