Documentation / Exploitation / Guides pratiques / Set the instance language

Set the instance language

The instance manifest's locale field picks the language behaviors write into persisted content — human-task titles, notification bodies, messages to the record — not the language of the console UI. This recipe sets that field and confirms it took effect.

Before you proceed, make sure this is the setting you actually want: see Instance vs UI locale for why these are two independent settings and what happens if you conflate them.

1. Confirm what locale affects

locale (libs/shared/src/plugin/instance.ts, InstanceManifest) is the language of the instance's own content, delivered to node behaviors as ctx.locale / ctx.t(...) (libs/shared/src/plugin/behavior.ts, PluginNodeContext):

/**
 * Langue de l'INSTANCE — celle du contenu PERSISTÉ (notifications au dossier,
 * titres de validation…). Une instance est monolingue : un établissement
 * français écrit son dossier en français.
 */
locale: z.string().default("fr"),

It does not affect the config-plane/EHR chrome, the plugin catalogue (node metadata, context kinds, declared events), or the plugin referential — those follow each user's own display locale (the meridian-locale cookie), resolved per request via ?locale= on /api/catalog, /api/plugins and /api/connections/protocols (apps/api/src/i18n.ts). Changing the instance locale will not change what the console reads in for any user.

An instance is monolingual by design: this is a one-time deployment choice, not a per-user preference, and content already written is never retranslated when you change it later.

A run waiting on a validation keeps the title it published. In a run of journal format 2, every run started by a platform release that knows it, the title, payload and deadline of a human task are journaled when the task starts, and a replay reads them back. A run of format 1 computes the title again at each resumption: a changed locale, or a changed translation of a title, blocks the runs of format 1 suspended on that task on a journal mismatch until the previous locale or plugin version is loaded again (see Recover runs blocked by a missing plugin). Change locale when no run of format 1 waits on a human task.

2. Set locale in the instance manifest

In the file INSTANCE_CONFIG points at (default instance.yaml at the repo root), set:

apiVersion: meridian/instance-v1
locale: fr   # language of content PERSISTED by runs (validations, notifications)

locale is a plain string with no enum constraint in the schema — it defaults to fr if omitted. In practice the values worth using are the ones your loaded plugins actually ship translations for (next step); an arbitrary locale code is accepted at parse time but will simply fall through to untranslated strings everywhere.

3. Check plugin translation coverage for that locale

Persisted strings come from each plugin's i18n/<locale>.yaml bundle, under its free-form runtime: section (behaviors call ctx.t("some.key", params) for text that isn't derived from the manifest). @posos/clinical is a concrete example — it ships both external-plugins/clinical/i18n/fr.yaml:

runtime:
  _:
    confirm-condition.title: Ajouter la condition « {display} » ?
    acknowledge-critical.title: "Acquitter le résultat critique : {display} = {value} {unit} ?"

and external-plugins/clinical/i18n/en.yaml with the same two keys in English. For each plugin your instance requires, check whether i18n/<your-locale>.yaml exists and has a runtime: section. This is diagnostic, not a hard gate — a missing bundle never fails the boot. The resolution order (libs/shared/src/plugin/i18n.ts, resolveRuntimeKey) is:

  1. the requested instance locale's bundle,
  2. the plugin's own source locale (its manifest locale:, fr by default),
  3. the raw key itself, verbatim.

So an uncovered locale degrades to a visible-but-untranslated string in production content, not an error. meridian-plugin i18n check <plugin-dir> (libs/plugin-cli/src/commands/i18n.ts) only validates the manifest-derived keys (node labels, descriptions, value-set concepts) used for UI localization — it does not check runtime: coverage, since those keys are free-form and not derivable from the manifest. To close a translation gap in a plugin you maintain, see Translate a plugin.

4. Restart the endpoint and proxy

Both processes read the instance manifest once, at process startup, not on every request:

// apps/api/src/restate/server.ts
const instance = loadInstance();
// apps/api/src/server/api.ts
const instance = loadInstance();

There is no hot reload — a manifest edit only takes effect after both processes restart:

docker compose restart endpoint proxy

(In pnpm run dev, restart the dev process instead.)

5. Verify

GET /api/catalog echoes the locale the running proxy loaded, without needing to trigger a run:

curl -s http://localhost:4000/api/catalog | jq .instanceLocale

For end-to-end confirmation, trigger a workflow that raises a human-task from a plugin you checked in step 3 (e.g. @posos/clinical's confirm-condition) and read the validation title produced — see Add human validation for how that title reaches the record. It should read in the language you set, not the language of whichever browser you're viewing it from.

97 documents6 sectionssource : /docs · généré au build