Skip to content
design system
Thème d’affichage, actuellement Auto

molecule · stable · since 2026-09

Toast

Purpose

The corner where the page says what just happened. A toast is a status message with a place on screen; what makes it heard is the region being present from the first render, and this component is that region, holding the messages the page gives it until the page or the user removes them. No timer.

When to use, when not

Use it for the outcome of an action the user does not need to answer: saved, exported, copied, failed with nothing to do. Not for an error that needs an answer (Alert in the page, or Dialog), not for a message the user must read before going on.

Anatomy

  1. The region, at the bottom right or in the flow.
  2. One item per message: the drawing, the sentence, the close button.

Props

Props of Toast
NameTypeDefaultWhat it does
messagesMessage[]The messages shown, newest last. The page removes one when it is done with it.
ondismiss?(id: string | number) => voidCalled with the id of the message the user closed. Without it, no close button.
fixed?booleantrueDrawn at the bottom of the screen; false keeps it in the flow, for a page that places it.
passthrough?booleanfalseClicks go through the messages: for a corner laid over controls the user is about to press, as the panel's bar of a wizard. Only without `ondismiss`, since a close button that cannot be pressed is a lie.
dismissLabel?string'Fermer le message'The close buttons' label.

States

In the flow, and with the success and error tones.

flow

The region is in the document from the first render, empty; each message added is announced, and the user closes it. Kept in the flow here.

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Toast, story flow, as Chromium renders it with forced colours active

passthrough

No close button and clicks go through: a confirmation laid over controls, removed by the page.

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Toast, story passthrough, as Chromium renders it with forced colours active

tones

Success and error tones: the line on the left and the drawing, the word in the message.

Light
Dark
320 px, light
320 px, dark
216 px, light
Forced colours, captured
Toast, story tones, as Chromium renders it with forced colours active

Accessibility contract

  • Role and name: status with aria-live="polite" on the region; each close button named by dismissLabel.
  • Keyboard, focus: a toast never takes the focus. The close buttons are in the tab order where the region sits, at the end of the page when fixed.
  • Live regions: this is one. Mount it with the page, once, and change messages.
  • Timing: no automatic removal. If a page removes a message itself, it waits long enough to read it and never removes one the user is interacting with.

Content rules

French. One sentence that says what happened: “Audit enregistré.”, “Rapport publié.”, “La connexion a été perdue.”

Do and don’t

  • Do mount one Toast per page, with the page; never one per message.
  • Do give every message a stable id, so closing one removes that one.
  • Do not put an action inside a toast; what needs an answer is a dialog.
  • Do set passthrough when the corner sits over controls the user is about to press, as the panel’s wizard bar; then the page removes the messages itself, since there is no close button.

Examples

<Toast messages={toasts} ondismiss={(id) => (toasts = toasts.filter((t) => t.id !== id))} />

Surfaces

  • Extension: the panel’s confirmations, rendered by the shell from a list of messages, with passthrough since the corner sits over a wizard’s bar.
  • App: the save and copy confirmations; not ported yet.

Related

LiveRegion, Alert.

Decisions

  • 2026-09-24: no timer. The extension’s toast vanished after two seconds, which is shorter than a sentence read by a screen reader; the page removes a message when it knows it can.
  • 2026-09-26: passthrough, for the panel. Its toast sat on a wizard’s Précédent / Suivant bar and a Firefox walk refused the click Chromium had let through; a status is not a control, and the click goes to the bar.
  • 2026-09-27: the fixed corner’s width counts its gutters. min(100%, 24rem) resolved to the viewport while the box sat 16 px from its right edge, and in the 216-pixel panel every message lost its left side.

Criteria held by construction

  • 7.5, Dans chaque page web, les messages de statut sont-ils correctement restitués par les technologies d'assistance ?
    One live region present from the first render holds every message; a message added to it is announced, where a toast created with its region is not.
  • 3.1, Dans chaque page web, l'information ne doit pas être donnée uniquement par la couleur. Cette règle est-elle respectée ?
    The tone is a line and a drawing; the message is the word, and says the same thing without them.
  • 11.9, Dans chaque formulaire, l'intitulé de chaque bouton est-il pertinent ?
    The close button is named 'Fermer le message', not an X.

Tokens it reads

  • Colour: --rl-c, --rl-ink, --rl-ink-soft, --rl-line-strong, --rl-nc, --rl-surface
  • Typography: --rl-text-sm
  • Spacing: --rl-space-2, --rl-space-3, --rl-space-4
  • Layout: --rl-radius, --rl-border-strong, --rl-z-toast