Messages tree. You can override any subset by passing a messages callback to <App>. Wire that callback to your i18n library and locale changes propagate into FlowDrop without a subscription.
FlowDrop is not an i18n library. It is a consumer of one. Translations live in your app, alongside the rest of your UI copy.
Quick start
Override a single string with a value:messages is DeepPartial<Messages> — every key is optional, missing keys fall through to the English defaults.
You can also pass a callback. The two forms are equivalent for static overrides; the callback is useful when your translations come from a function call you’d rather not invoke unless the prop is actually read:
Translating with paraglide-js
Paraglide-js compiles your.json translation files into typed message functions. Wire them into FlowDrop’s messages prop:
paraglide-js is one option — sveltekit-i18n, typesafe-i18n, or any reactive store will work. The contract is just: a callback returning a partial tree.
Why the callback re-runs on locale change
Why the callback re-runs on locale change
Passing
messages as a callback (not a plain object) is what makes locale
switching reactive. Paraglide’s reactive locale store causes Svelte to
re-evaluate the expression; FlowDrop’s root then re-derives the merged message
tree and re-renders.The Messages shape
The full default tree lives atlibs/flowdrop/src/lib/messages/defaults.ts and is exported as defaultMessages from @flowdrop/flowdrop/core. The shape is grouped by domain, not by component — file paths churn, domains don’t.
Parameterised entries are functions, not template strings:
({ n: _n }) => 'Move up'.
Removed label props
Several components used to accept individual*Label props that duplicated the messages tree. These duplicates are removed — use the corresponding messages key instead:
<FormToggle>’s onLabel/offLabel and <FormArray>’s addLabel are not removed. They express per-instance labels the global messages system cannot (a toggle’s “Hidden”/“Visible”, a schema-derived “Add Header” button) and are documented overrides.
Workflow-level overrides on interrupt configs (config.confirmLabel, config.acceptAllLabel, etc.) are not removed either — those are runtime data from the workflow author, not component-prop API. They keep their priority over the messages defaults.
Components used outside the <App> provider
If you mount a flowdrop component (e.g. <SchemaForm> standalone, or a Storybook story) outside the root <App>, it falls back silently to the English defaultMessages. There is no error. The trade-off: a missing provider always renders English regardless of locale. To get translations in standalone usage, set up the messages context yourself:
setMessages accepts a getter so reactive overrides propagate the same way they do under <App>.
Reference
- Defaults:
libs/flowdrop/src/lib/messages/defaults.ts - Public types:
Messages,MessagesOverride(re-exported from@flowdrop/flowdrop) - Source:
libs/flowdrop/src/lib/messages/