Snackbar
MD3 snackbar: a brief message at the bottom of the screen with an optional
action. Wrap your app in SnackbarProvider and call useSnackbar().show()
— the provider queues snackbars, times them out, places them and animates
them in and out.
Showing snackbars
show() takes a message string or options and returns a promise that
resolves with why the snackbar closed: 'action', 'dismiss',
'timeout' or 'escapeKeyDown'. Snackbars show one at a time; later calls
queue behind the current one.
// Once, near the root (inside ThemeProvider):
<SnackbarProvider>
<App />
</SnackbarProvider>
// Anywhere below it:
const { show } = useSnackbar()
const reason = await show({ message: 'Conversation archived', actionLabel: 'Undo' })
if (reason === 'action') restoreConversation()
Duration
duration is 'short' (4s), 'long' (10s), 'indefinite', or a number
of milliseconds. It defaults to 'indefinite' when there is an action
(the snackbar stays until the user acts) and 'short' otherwise. The
timer pauses while the snackbar is hovered or has focus inside it. Add
withDismissAction to show a close button — recommended for indefinite
snackbars. close() from useSnackbar() closes the current one.
show({ message: 'Connection lost', duration: 'long', withDismissAction: true })
show({ message: 'Saved', duration: 2500 })
Long action
actionOnNewLine places the action on its own line below the message,
end-aligned — for a long action label. It is opt-in; the layout is never
chosen automatically.
The Snackbar component
Snackbar is the presentational bar the provider renders. Use it directly
only when you manage placement and timing yourself: action takes
{ label, onClick } (rendered as a text button) or a custom node, and
onDismiss(event, reason) adds the dismiss icon button. Standalone, it is
a polite live region (role="status"); override role / aria-live when a
surrounding host already provides the live region.
<Snackbar
message="Conversation archived"
action={{ label: 'Undo', onClick: undo }}
onDismiss={(event, reason) => hide()}
/>
Accessibility
- The provider mounts one persistent polite live region
(
role="status") and only swaps its content, so screen readers announce every message. - Escape dismisses a snackbar while focus is inside it; when a focused snackbar closes, focus returns to where it was before.
- Auto-dismiss pauses on hover and focus (WCAG 2.2.1). Snackbars with an action stay until the user acts by default.
- Information in an auto-dismissing snackbar must also be available elsewhere in the UI; for snackbars with an action, consider a documented shortcut that moves focus to it.
- Keep messages short and plain — no inline links or icons. Localize the
dismiss button with
dismissLabel.
Props
SnackbarProvider
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Class for the host (the fixed, bottom-centered placement container). |
style | CSSProperties | — | Style for the host — e.g. raise it above a bottom navigation bar with `{ bottom: 80 }`. |
Snackbar
| Prop | Type | Default | Description |
|---|---|---|---|
action | ReactNode | SnackbarAction | — | Optional single action — an `{ label, onClick }` text button (rendered as an inverse-primary `Button variant="text"`) or a custom node (m3: never a filled or elevated button). |
actionOnNewLine | boolean | false | Places the action on its own line below the message, end-aligned — for a long action label (m3 "two lines with longer action"; Compose `actionOnNewLine`). Opt-in only; the layout is never chosen automatically. |
dismissLabel | string | Dismiss | Accessible label of the dismiss icon button. |
message * | ReactNode | — | The message text (supporting text). Keep it short and plain — m3 advises against stylized text, inline links and icons in snackbars. |
onDismiss | ((event: SyntheticEvent<HTMLElement, Event>, reason: SnackbarDismissReason) => void) | — | When provided, shows a trailing dismiss (close) icon button, and pressing Escape while focus is inside the snackbar also dismisses it. Receives the triggering event and the reason. |
useSnackbar().show() options
| Option | Type | Default | Description |
|---|---|---|---|
message | ReactNode | — | The message text. Keep it short and plain. |
actionLabel | string | — | Label of the single action button; activating it resolves 'action'. |
withDismissAction | boolean | false | Show a trailing dismiss (close) icon button. |
duration | 'short' | 'long' | 'indefinite' | number | 'indefinite' with an action, else 'short' | How long the snackbar stays; pauses on hover / focus. |
actionOnNewLine | boolean | false | Place the action on its own line. |
dismissLabel | string | 'Dismiss' | Accessible label of the dismiss icon button. |