Languages
Give your module's text a default, translations and an editor on the Lang page.
A lang class lists the text your module sends, such as API messages or bot replies. Admins can reword any of it on the Lang page, per language, and your code reads the result.
Supported Languages
en, fr, es-ES, de, pt-BR, it, nl, pl, ru, uk, tr, sv-SE, ja, ko, zh-CN, zh-TW
English is the base. Kora looks up text in the server's Language, then its Secondary Language, then English, and uses the first one that has the key.
Defining Text
Put the English class in resources/lang/en/:
import { Langs } from "#kora/modules";
export class ExampleMessages extends Langs {
constructor(kora) {
super(kora, { name: "messages", label: "Messages", description: "Text sent by the example API" });
}
schema() {
return {
replies: {
type: "section",
label: "Replies",
fields: {
synced: { type: "phrase", default: "Synced %count% licenses.", label: "Synced" },
failed: { type: "phrase", default: "Sync failed: %reason%", label: "Failed" }
}
},
footer: { type: "text", default: "Thanks for buying from us.", label: "Footer" }
};
}
}| Type | Editor |
|---|---|
phrase | One line. The default when type is left out. |
text | Several lines. |
section entries group fields under a heading, the same as in config classes. A field can also be a bare string, such as synced: "Synced %count% licenses.".
Translations
Every other language is a JSON file named after the group, holding only the keys you translate:
resources/lang/
├── en/
│ ├── common.json
│ └── messages.js
├── de/
│ ├── common.json
│ └── messages.json
└── fr/
├── common.json
└── messages.json{
"synced": "%count% Lizenzen synchronisiert.",
"failed": "Synchronisierung fehlgeschlagen: %reason%"
}Missing keys fall back through the chain above. Folders for languages Kora does not support are skipped.
You can also put every language in one resources/lang/translations.json, keyed by language and then group:
{
"de": { "messages": { "synced": "%count% Lizenzen synchronisiert." } },
"fr": { "messages": { "synced": "%count% licences synchronisées." } }
}Reading Text
this.kora.modules.lang.phrase("example", "messages", "synced", { count: 12 });
this.kora.modules.lang.value("example", "messages", "footer");
this.kora.modules.lang.values("example", "messages");phrase replaces each %token% with the value you pass. If the key does not exist it returns the key itself, so a typo shows up instead of an empty message.
All three use the server's language and include anything an admin changed on the Lang page.
Admin Edits
The Lang page lists every module with a lang class. An admin picks a language and changes any field. Edits are saved per language under lang:<module> in Kora's settings and win over your defaults and JSON files. When editing another language, the English text is shown under each field.
Dashboard Text
common.json holds the text the dashboard shows for your module, in each language:
{
"name": "Beispiel",
"description": "Synchronisiert Lizenzen mit einem anderen Dienst",
"schema.example.config.settings.label": "Beispiel",
"schema.example.config.settings.token.label": "API-Token"
}| Key | Translates |
|---|---|
name | The module name in the sidebar and module list. |
description | The module description. |
schema.<module>.config.<group>.label | A config group's heading. |
schema.<module>.config.<group>.<field>.label | A config field's label. |
schema.<module>.lang.<group>.<field>.label | A field's label on the Lang page. |
Any other key is added to the dashboard dictionary as is, so your pages can use it. Kora's own dashboard text lives in src/dashboard/lang/<code>/common.json and is not part of a module.