Toast
A brief message after something happened: "Server added". Raised from the browser or flashed by the server.
Examples
From the browser
toast() works from any island or script. Errors stay until dismissed; others go after 5s, paused on hover or focus.
import { toast } from '@switchboard/ui'
toast({ tone: 'success', title: 'Server added', body: 'GitHub is patched in with 38 tools.' })
toast({ tone: 'info', title: 'Tools refreshed', body: 'Linear listed 14 tools.' })
toast({ tone: 'warning', title: 'Token expires in 2 days', body: '…' })
toast({ tone: 'error', title: 'Could not reach Notion', body: 'The server returned 401. Check its token.' })From the server (flash)
This form posts, the action sets a signed flash cookie and redirects (303) back here, and the page passes the flash to its Toaster. Works without JavaScript.
// action
return redirect(routes.settings.href(), {
status: 303,
headers: await flash.headers({ tone: 'success', title: 'Settings saved' }),
})
// page
let { flash: messages, headers } = await flash.read(context.request)
return context.render(<SettingsPage flash={messages} />, { headers })Usage
import { Toaster, toast } from '@switchboard/ui'
// Once per page, at the end of the document.
<Toaster flash={flash} />
// Once per app.
export const flash = createFlash({ secrets: [env.FLASH_SECRET] })Props
Every component also takes mix, for css() and mixins applied after its own style.
Toaster
| Prop | Type | Default | Description |
|---|---|---|---|
| flash | ToastMessage[] | – | Messages to show on load, read from the flash cookie after a redirect. A new value after client navigation shows again. |
Mount exactly one per page.
toast(message)
| Prop | Type | Default | Description |
|---|---|---|---|
| title* | string | – | Past tense of the action: "Server added". |
| tone | 'success' | 'error' | 'warning' | 'info' | 'info' | Icon and colour. Errors also get role="alert" and persist. |
| body | string | – | One sentence of detail. |
| action | { label: string; href: string } | – | A follow-up link, e.g. "View". Same-origin paths only in flashes. |
| duration | number | 5000 (errors: 0) | Milliseconds before it goes. 0 keeps it until dismissed. |
Browser only; a no-op on the server. Accepts a ToastMessage or a plain title string.
Accessibility
- The region is aria-live="polite" and labelled "Notifications"; error toasts have role="alert".
- Timers pause while the pointer or focus is inside the stack, and every toast has a "Dismiss notification" button.
- Toasts never take focus; put anything the person must act on in the page, not only in a toast.
Guidance
Do
- Confirm a finished action in the past tense: "Server added", "Token rotated".
- Use the server flash after a POST redirect so it works without JavaScript.
Don’t
- Mount a second Toaster.
- Use a toast for a state that lasts, like a failing server; use a Lamp or Callout.
- Show form validation errors in a toast; put them on the field.