Skip to content

Toast

A brief message after something happened: "Server added". Raised from the browser or flashed by the server.

FeedbackIsland

Examples

From the browser

toast() works from any island or script. Errors stay until dismissed; others go after 5s, paused on hover or focus.

Example
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.

Example
// 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

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

Toaster props
PropTypeDefaultDescription
flashToastMessage[]–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)

toast(message) props
PropTypeDefaultDescription
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.
bodystring–One sentence of detail.
action{ label: string; href: string }–A follow-up link, e.g. "View". Same-origin paths only in flashes.
durationnumber5000 (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.