The problem
Something happens, and the interface has to tell the reader — but “something happened” covers wildly different situations. The reader just clicked Save and needs a quick confirmation they can miss without consequence. A campaign’s routing has been degraded for an hour and every page they visit should say so until it’s fixed. A field they’re editing right now is invalid. An export they started five minutes ago, before navigating to a different screen entirely, has just finished. Titan ships two of the four components this needs — Toast and Alert — with clear jobs and no shared vocabulary for choosing between them at the composition level. It ships zero for the third: a persistent, page-independent condition. And it has no answer at all for the fourth: telling someone about something that finished outside the view they’re currently looking at. Using the wrong surface for the wrong situation has a real cost in both directions. A toast for a billing problem disappears in five seconds and the reader never sees it again. An alert used for “your change was saved” becomes furniture nobody reads, sitting in the exact spot where the next real problem needs to appear.Decide first: whose action, and how long does it matter?
When this applies
- Deciding which surface tells the reader about an outcome, a standing condition, or something that finished outside their current view.
When it doesn’t
Structure
Behavior
Constraints
Content
Accessibility
A toast’s 5-second default may not give a screen-reader user enough time to hear a longer message. This is not a proposal fix — it’s a real, documented limitation of the shipped component. Passpersist: true for anything longer than a short confirmation, per
Toast’s own accessibility notes.
An Alert’s live-region role depends on when it appears. Set role="alert" for a message
that must interrupt now, and role="status" for one that can wait for a pause — never
role="alert" on an alert present at page load, since a live region with content already in it
on load announces nothing. See TITAN-ALR-08.
An in-app notification indicator (proposal) should announce a changed count politely, not
interrupt. An unread badge changing from 1 to 2 is not urgent enough to cut off whatever the
reader is doing — aria-live="polite" on the count, not "assertive".