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: įŽäŊ䏿
| Option | Description |
|---|---|
default | Default locale used when a request does not include a locale identifier or requests an unsupported locale |
enabled | Whether multilingual support is enabled; when disabled, the frontend hides the language switcher |
locales | Runtime 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:
- Add the language code and native display name to
i18n.localesinconfig.yaml. - Create core framework language packs under
apps/lina-core/manifest/i18n/<locale>/. - Add language packs under
manifest/i18n/<locale>/for every enabled plugin. - 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:
| Scope | Description |
|---|---|
| Specific locale | Refresh only one locale |
| Specific plugin | Refresh only one plugin's language resources |
| Core framework resources | Refresh only core framework language packs |
| API documentation resources | Refresh 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:
| Language | Code |
|---|---|
| Simplified Chinese | zh-CN |
| Traditional Chinese | zh-TW |
| English | en-US |
| Japanese | ja-JP |
| Korean | ko-KR |
Directory names, locale fields in config.yaml, and frontend request locale parameters should stay consistent.