Skip to content
DomainKit
Esc
navigateopen⌘Jpreview
On this page

Outcome

Render a failed step as media, a title, a description, and the action that follows, in a card or on one line, with the words coming from the message catalog.

Every flow ends a failed step in an Outcome: what happened, what to do about it, and the retry the flow allows. Connect.Outcome, Provision.Outcome, Cleanup.Outcome, and Verify.Outcome bind their controller to the same parts, so a failure reads the same way everywhere.

/** The default composition, then one the host writes itself. Both take their words from the catalog. */
export function ConnectionOutcome() {
  const controller = Connect.useController({ domain });
  return (
    <>
      <Connect.Outcome controller={controller} />
      <Connect.Outcome controller={controller} layout="inline">
        <Outcome.Media variant="default">
          <MyIcon />
        </Outcome.Media>
        <Outcome.Title />
        <Outcome.Content />
      </Connect.Outcome>
    </>
  );
}

Usage

/** The default composition, then one the host writes itself. Both take their words from the catalog. */
export function ConnectionOutcome() {
  const controller = Connect.useController({ domain });
  return (
    <>
      <Connect.Outcome controller={controller} />
      <Connect.Outcome controller={controller} layout="inline">
        <Outcome.Media variant="default">
          <MyIcon />
        </Outcome.Media>
        <Outcome.Title />
        <Outcome.Content />
      </Connect.Outcome>
    </>
  );
}

Anatomy

Part Renders
Outcome.Root The panel, with data-layout, data-tone, and role="alert"
Outcome.Header Media, title, and description together
Outcome.Media The glyph for the tone, framed (icon) or bare (default)
Outcome.Title The catalog’s heading for the reason
Outcome.Description The catalog’s sentence about what to do next
Outcome.Content The actions, starting with the flow’s retry

X.Outcome with no children renders that composition. With children it renders yours, and the binding stays: Outcome.Title and Outcome.Description still read the catalog, and Outcome.Content still holds the flow’s retry.

Layout and tone

layout="card" is a dashed panel with the media above the words, for a flow that has room. layout="inline" puts the media, the title, and the action on one line, for the row under a form field or beside a step in progress.

data-tone is danger for a failure and warning for a receipt that only partly landed. Each tone draws its own glyph from icons on DomainKit.Root and colours itself from --domainkit-danger, --domainkit-warning, and --domainkit-success. tone and layout on Outcome.Root override what the flow resolved, and every part below reads the override.

Words

Messages.outcome(error, catalog, context) returns the { title, description } pair for a reason. The context names the provider the customer acted on, which is what lets a rejected token read “Cloudflare didn’t accept this token” rather than naming an HTTP status. Messages.failure returns the same pair as one sentence, for a host that renders text rather than a card.

Override one reason on DomainKit.Root:

<DomainKit.Root
  messages={{
    unauthenticated: (_reason, context) => ({
      title: `${context.provider ?? "That provider"} turned down the token`,
      description: "Create a token with DNS edit rights and paste it again.",
    }),
  }}
  transport={transport}
/>

Read-only

A retry is a write, so Outcome.Content renders nothing when the flow is read-only and the failure stays on screen. Verification is the exception: observing reads the world rather than changing the domain, so its retry stays.

Was this page helpful?