docs: reflect the config, branding, i18n and plugin-API changes

- config.md: add server.guestIdent, report.service, defaults.lang; correct the
  turnstile.enabled / features.* descriptions; add a Languages section; complete example.
- branding.md: branding.name/icon now drive the favicon, notifications, PWA and push;
  fix the feature-flag notes; add a Languages note.
- plugins.md: document orbit.config() and orbit.i18n (language/t/pick) + a Localization
  section; note they arrived in apiVersion 4.
- overview.md: add the 10-language support bullet.
This commit is contained in:
Jean Chevronnet 2026-07-04 01:05:11 +00:00
parent d4d93bfd39
commit 6dfb7631b2
No known key found for this signature in database
4 changed files with 68 additions and 15 deletions

View file

@ -21,8 +21,10 @@ Everything that ties Orbit to a particular network or brand lives in
} }
``` ```
This changes the connect screen, the console title, the network icon, and the CTCP VERSION/SOURCE `branding.name` and `branding.icon` reach **everywhere** the app identifies itself: the connect
replies the client sends. screen, the browser tab title + **favicon**, desktop and Web Push notifications, the PWA install
prompt (name + description, localized), the iOS home-screen title, the network icon, and the CTCP
VERSION/SOURCE replies. Point `icon` at your own logo URL and the tab icon follows.
## Themes ## Themes
@ -49,6 +51,11 @@ Hide whole features per deployment:
{ "features": { "push": true, "imageUpload": true, "register": false } } { "features": { "push": true, "imageUpload": true, "register": false } }
``` ```
- `push` — the Web Push notifications row. - `push` — Web Push notifications: the Settings row **and** the re-subscribe-on-connect.
- `imageUpload` — the composer image button + paste/drag upload. - `imageUpload` — the composer image button **and** paste / drag-drop upload.
- `register` — the "create an account" tab. - `register` — account self-service: the "Create account" button, the "Forgot password" link, and their FAQ entries (all hidden together).
## Languages
The UI and the bundled plugins are fully translated in **10 languages** (auto-detected). Pin a
default with [`defaults.lang`](https://orbit.tchatou.fr/docs/config/); users can switch in Settings.

View file

@ -18,30 +18,47 @@ Merge rules: objects merge key-by-key; **arrays and scalars replace** wholesale.
| Key | Type | What it does | | Key | Type | What it does |
|-----|------|--------------| |-----|------|--------------|
| `server.url` | string | WebSocket URL of the IRCv3 server. | | `server.url` | string | WebSocket URL of the IRCv3 server. |
| `server.guestIdent` | string | Ident for **guests** (not logged in) — e.g. `Foo!Invité@…`. Folded to ASCII (IRC idents are `[A-Za-z0-9._-]`, so `Invité``Invite`). Logged-in members use their own nick as the ident. |
| `startup.channels` | string[] | Channels auto-joined (first = active). A `?channel=` URL param overrides. | | `startup.channels` | string[] | Channels auto-joined (first = active). A `?channel=` URL param overrides. |
| `branding.name` | string | App/network name shown in the UI + CTCP VERSION. | | `branding.name` | string | App/network name — UI, tab title, **notifications**, **PWA install prompt**, and CTCP VERSION. |
| `branding.icon` | string | Logo / favicon URL. | | `branding.icon` | string | Logo/icon — connect screen, **browser favicon**, desktop + push notifications, PWA. |
| `branding.url` | string | Homepage (used in CTCP VERSION/SOURCE). | | `branding.url` | string | Homepage (used in CTCP VERSION/SOURCE). |
| `branding.tagline` / `taglineEm` / `subtitle` | string | Connect-screen copy. | | `branding.tagline` / `taglineEm` / `subtitle` | string | Connect-screen copy. |
| `branding.projectUrl` | string | "Powered by Orbit" link in Settings. | | `branding.projectUrl` | string | Orbit project/source link (Settings → About). |
| `turnstile.enabled` / `sitekey` | bool / string | Cloudflare Turnstile on registration. | | `turnstile.enabled` | bool | Render the anti-bot challenge inline (Cloudflare Turnstile). `false` = show the server's verification step as a link, no Cloudflare script. Whether a challenge is *required* is decided server-side. |
| `report.target` | string | Channel that user reports are sent to. | | `turnstile.sitekey` | string | Public Turnstile site key. |
| `report.service` | string | Services pseudo-client that receives reports (e.g. `ReportServ`) — not blocked by a `+n` staff channel. Empty = fall back to `report.target`. |
| `report.target` | string | Channel that reports are sent to when `report.service` is empty. |
| `defaults.theme` | string | `light` · `dark` · `yomirc` · `yomirc-dark`. | | `defaults.theme` | string | `light` · `dark` · `yomirc` · `yomirc-dark`. |
| `defaults.compact` / `sound` / `hideJoinQuit` / `clock24` | bool | Preset new-user prefs. | | `defaults.compact` / `sound` / `hideJoinQuit` / `clock24` | bool | Preset new-user prefs. |
| `features.push` / `imageUpload` / `register` | bool | Turn whole features on/off. | | `defaults.lang` | string | Force the UI language (`en`, `fr`, `de`, `es`, `it`, `tr`, `ru`, `ne`, `pt-BR`, `pt-PT`). Empty = auto-detect from the browser. |
| `features.push` | bool | Web Push notifications — the Settings row **and** the re-subscribe-on-connect. |
| `features.imageUpload` | bool | Composer image button **and** paste / drag-drop upload. |
| `features.register` | bool | Account self-service: the "Create account" button, the "Forgot password" link, and their FAQ entries. |
| `plugins` | string[] | Plugin script URLs loaded at startup. See [Plugins](https://orbit.tchatou.fr/docs/plugins/). |
> `defaults.*` only seed a user's preferences the **first** time — once someone changes a setting, > `defaults.*` only seed a user's preferences the **first** time — once someone changes a setting,
> it's stored in their browser and the config no longer overrides it. > it's stored in their browser and the config no longer overrides it.
## Languages
The UI ships fully translated in **10 languages** — English, French, German, Spanish,
Italian, Turkish, Russian, Nepali, and Brazilian + European Portuguese. Orbit
auto-detects the visitor's browser language; pin a default with `defaults.lang` (users
can still switch in **Settings**). The bundled plugins are localized too — see
[Plugins](https://orbit.tchatou.fr/docs/plugins/).
## Example ## Example
```json ```json
{ {
"server": { "url": "wss://irc.example.org/ws/" }, "server": { "url": "wss://irc.example.org/ws/", "guestIdent": "Guest" },
"startup": { "channels": ["#lobby", "#help"] }, "startup": { "channels": ["#lobby", "#help"] },
"branding": { "name": "ExampleChat", "tagline": "Chat with", "taglineEm": "everyone." }, "branding": { "name": "ExampleChat", "icon": "https://example.org/logo.svg", "tagline": "Chat with", "taglineEm": "everyone." },
"turnstile":{ "enabled": false, "sitekey": "" }, "turnstile":{ "enabled": false, "sitekey": "" },
"defaults": { "theme": "dark", "compact": true }, "report": { "service": "ReportServ", "target": "#staff" },
"features": { "register": false } "defaults": { "theme": "dark", "compact": true, "lang": "" },
"features": { "push": true, "imageUpload": true, "register": false },
"plugins": []
} }
``` ```

View file

@ -20,6 +20,9 @@ network** and **rebranded** from a single `config.json` — without recompiling.
[config.json reference](https://orbit.tchatou.fr/docs/config/). [config.json reference](https://orbit.tchatou.fr/docs/config/).
- **Installable PWA.** Mobile-first layout, offline app shell, and notifications when the tab is - **Installable PWA.** Mobile-first layout, offline app shell, and notifications when the tab is
closed. closed.
- **Speaks 10 languages.** The UI, system messages, and the bundled plugins are fully translated
and auto-detected (English, French, German, Spanish, Italian, Turkish, Russian, Nepali, and
Brazilian + European Portuguese). Pin a default with `defaults.lang`.
- **Self-hostable.** A static build behind any web server. The project even runs its own git - **Self-hostable.** A static build behind any web server. The project even runs its own git
server with [push-to-deploy](https://orbit.tchatou.fr/docs/push-to-deploy/). server with [push-to-deploy](https://orbit.tchatou.fr/docs/push-to-deploy/).
- **Free software.** AGPL-3.0 — use it, modify it, self-host it. - **Free software.** AGPL-3.0 — use it, modify it, self-host it.

View file

@ -73,6 +73,10 @@ instead. See **[Compiled plugins](https://orbit.tchatou.fr/docs/compiled-plugins
| `orbit.irc.list()` | request the channel list | | `orbit.irc.list()` | request the channel list |
| `orbit.themes.current()/list()/set(id)` | read/set the theme | | `orbit.themes.current()/list()/set(id)` | read/set the theme |
| `orbit.storage.get(key, def)/set(key, val)` | namespaced persistence | | `orbit.storage.get(key, def)/set(key, val)` | namespaced persistence |
| `orbit.config()` | the resolved runtime config (branding, features, …) |
| `orbit.i18n.language()` | current UI language code (e.g. `es`, `pt-BR`) |
| `orbit.i18n.t(key, opts?)` | translate an app locale key (supports `{{interpolation}}`) |
| `orbit.i18n.pick(table)` | pick a string from a `{ lang: text }` table by the current language |
| `orbit.addUi(slot, render)` | add UI to a slot (returns a remover) | | `orbit.addUi(slot, render)` | add UI to a slot (returns a remover) |
| `orbit.addSettingsSection({label, icon?, render})` | add a whole Settings section | | `orbit.addSettingsSection({label, icon?, render})` | add a whole Settings section |
| `orbit.h / orbit.html` | render helpers | | `orbit.h / orbit.html` | render helpers |
@ -94,6 +98,28 @@ instead. See **[Compiled plugins](https://orbit.tchatou.fr/docs/compiled-plugins
More slots (message decorators, side panels) will be added as the core grows More slots (message decorators, side panels) will be added as the core grows
stable homes for them. stable homes for them.
### Localization (i18n)
The UI ships in 10 languages — keep your plugin in step so it isn't stuck in one. Two ways:
- **Self-contained** — carry a `{ lang: text }` table and let Orbit pick the current language:
```js
const LABEL = { en: 'Copy', fr: 'Copier', de: 'Kopieren' };
orbit.html`<button title=${orbit.i18n.pick(LABEL)}>⧉</button>`;
```
- **Interpolated**`orbit.i18n.t('key', { name })` resolves an app locale key with
`{{placeholders}}`, so word order is correct per language. The four bundled plugins
(clock, copy, invite, games) use this.
Read the string **at render time**, not once at load: plugin UI re-renders when the language
changes, so the text follows automatically. `orbit.i18n.language()` returns the current code
if you need to branch.
> `orbit.i18n` and `orbit.config()` were added in **`apiVersion` 4** — guard with
> `if (orbit.apiVersion >= 4)` if your plugin must run on older builds.
## Trust & security ## Trust & security
Plugins are **operator-controlled**: a deployment lists them in `config.json`, so Plugins are **operator-controlled**: a deployment lists them in `config.json`, so