# Localization

# Localization

Info Hub has two kinds of texts:

- **Interface texts** (buttons, labels, messages) ship in 9 languages in the `localization/` folder.
- **Your content** (rules, FAQ, news, pages, team, tiles, server info, hub title) is written in the content files, and every piece can carry translations in an `i18n` map.

## Bundled Languages

| Code | Language |
|------|----------|
| `en-US` | English (default fallback) |
| `de-DE` | German |
| `fr-FR` | French |
| `es-ES` | Spanish |
| `pt-BR` | Portuguese (Brazil) |
| `ru-RU` | Russian |
| `pl-PL` | Polish |
| `tr-TR` | Turkish |
| `it-IT` | Italian |

The localization version of 3.1.1 is **13** (unchanged since 3.1.0).

---

## Player language

Players choose their language for all KyuubiSoft mods with `/kslang <code>` or, with KyuubiSoft Core 2.8.0+, in the shared settings window `/kssettings`. The server's default player language and whether players may choose are set there too. Without Core, the `language` field in `config.json` is the server default.

---

## Content translations (`i18n`)

Every rule category, rule, FAQ category and entry, news entry, custom page and its entries, server link, team rank and member, quick-access category and button, the server name / tagline / description and the hub title accept an optional `i18n` map. The keys inside are the item's own field names:

```json
{
  "id": "no-griefing",
  "title": "No griefing",
  "shortText": "Do not destroy other players' builds.",
  "i18n": {
    "de-DE": {
      "title": "Kein Griefing",
      "shortText": "Zerstöre keine Bauten anderer Spieler."
    }
  }
}
```

A player sees: their language (the same primary language also matches, e.g. `de-AT` uses `de-DE`), then the server default language, then the plain field.

In the [admin window](./admin-panel#texts-per-language) every text field has language chips (translated / missing / outdated). A missing language shows what players see today in grey and is never saved; when the base text changes, translations are flagged as outdated instead of being deleted.

The welcome message has its own per-language lines in `joinMessage.i18n`, see [Configuration](./configuration).

---

## Interface text files

```
mods/kyuubisoft_infohub/localization/
├── en-US.json ... it-IT.json   # shipped texts (replaced on updates)
├── custom_en-US.json           # your overrides for English (optional)
└── custom_de-DE.json           # your overrides for German (optional)
```

### Custom overrides

Create `custom_<lang>.json` with only the keys you want to change:

```json
{
  "message.no_permission": "You are not allowed to do that."
}
```

Custom files are loaded **after** the shipped file, so only the keys you specify are overridden, and they are never overwritten by updates. Translation edits from the KyuubiSoft web editor are also saved into `custom_<lang>.json` (only real overrides; the language code is checked against the shipped languages).

### Key namespaces

| Prefix | Used for |
|--------|----------|
| `infohub.book.*` | The Info Hub book (tabs, chips, buttons, messages) |
| `ihadmin.*` | The admin window |
| `admin.cmd.*` | `/ksinfoadmin` chat replies |
| `message.*` | General chat messages |
| `commands.*` | Command browser parameters and placeholders |

### Automatic version updates

Each shipped language file has a `_localization_version`. When a new version brings new texts, the plugin backs up the old file as `<lang>.json.backup-v<old version>`, extracts the new one and logs it. Your `custom_*.json` files are untouched.

:::caution
Do not edit the shipped files directly; they are replaced on updates. Use `custom_*.json`.
:::

---

## Placeholders

Interface texts use numbered placeholders (`{0}`, `{1}` ...). They are filled in one pass, so a value that itself contains `{1}` (for example a command) is shown as written. The join message replaces `{player}` and `{server}`.

---

## Best Practices

1. **Write content in your server language first**, then add translations in the admin window.
2. **Use custom files** for interface texts so your changes survive updates.
3. **Test in game** - some strings may be too long in some languages.