---
title: Words and outcomes
description: Replace any sentence the flow puts on screen through the message catalog, and render a failed step from the title and description its reason resolves to.
sidebar:
  label: Words
seo:
  title: Localise the DomainKit React flow
---

Nothing in `@domainkit/react` renders a tag, a status literal, or a reason name. Every user-visible
string arrives from `Messages.Catalog` first, so one prop translates the whole surface.

## Messages

`Messages.Catalog` holds every user-visible string. Actions, progress, connection, plan review,
records, receipts, verification, and failures are the labeled groups. Failures have one function per
`DomainKit.Error` reason. Callback recovery adds `recoveryCancelled(provider)`,
`recoveryRestart(provider)`, and `recoveryInspect(provider)`, each a title and description. `retry`
and `dismissRecovery` are the action labels. The catalog is closed, so every key has a default in
`Messages.english`; `messages` on `DomainKit.Root` takes a `Partial<Catalog>` and merges over it,
and a host replaces one key without restating the rest. `DomainKit.useMessages()` returns the merged
catalog to a component of your own.

An operation becomes a sentence through `operation`, a conflict becomes a reason and an advice
through `conflictReason` and `conflictAdvice`, and a token field name becomes a label through
`fieldLabel`, which spaces out a name such as `accountId` until a host labels the field itself.

The verification group phrases what a failing check found: `expectedValue(value)`,
`observedValues(values)`, and `observedNothing`. The only observer text that reaches a customer
unwrapped is the `detail` the observer itself wrote.

`administratorConnects(provider)` is what a read-only surface says where a connect control would
otherwise be, and `notConnected` is what it says when no provider serves the zone at all.

## Outcomes

A failure carries the `DomainKit.Error` itself, so a surface reads `reason`, `category`, and
`isRetryable` rather than parsing text. `Outcome.useDescribe()` binds the catalog and returns the
pair the reason resolves to: a heading the customer reads first, and what to do about it.

<Snippet file="examples/react/controllers.tsx" region="failure" title="A failed connect" />

<Component path="registry/outcome" />

The reason alone cannot name the provider the customer typed a token for, so the surface supplies it
in the context. `Outcome.describe(error, catalog)` is the same answer without a React context, for a
server render or a log line.

## Provider artwork

Provider marks are the host's, and the registry's `provider-row` takes them keyed by provider id.
Whatever you pass is the mark: nothing wraps it in a tile, so a circular logo stays a circle. Without
an entry the mark is the provider's initial, and nothing is fetched while the row renders.

<Component path="registry/provider-row" />
