Toast
A toast is a short, time-limited notification that appears in a corner
of the screen. The installToast behavior listens for hc:toast
events on document.body, renders the toast into the page’s toast
region, and auto-dismisses it after a few seconds.
Markup
Section titled “Markup”The toast region is a single host element. Place it once near the end
of <body>. If the region is missing, the behavior creates one
automatically.
<div class="hc-toast-region" data-hc-toast-region role="region" aria-label="Notifications"></div>Triggering a toast
Section titled “Triggering a toast”From the client
Section titled “From the client”Dispatch a bubbling hc:toast event with a detail object:
document.body.dispatchEvent( new CustomEvent('hc:toast', { bubbles: true, detail: { message: 'Saved', variant: 'success' }, }));Try it — each button dispatches the event above. The toast appears in the page corner (and auto-dismisses):
// installToast() must be installed (it is in the behaviors bundle).saveButton.addEventListener('click', () => { document.body.dispatchEvent(new CustomEvent('hc:toast', { bubbles: true, detail: { title: 'Saved', message: 'Changes saved.', variant: 'success' }, }));});From the server (htmx)
Section titled “From the server (htmx)”Return an HX-Trigger response header. htmx dispatches hc:toast on
the body for you.
HTTP/1.1 200 OKHX-Trigger: {"hc:toast":{"message":"Saved","variant":"success"}}For multiple events in one response:
HX-Trigger: {"hc:toast":{"message":"Saved","variant":"success"}, "items:refresh":true}Detail shape
Section titled “Detail shape”| Field | Type | Default | Notes |
|---|---|---|---|
message | string | (required) | The body text. |
title | string | (omitted) | Bold one-liner above the message. |
variant | string | 'info' | info / success / warning / error. |
duration | number | 4500 | Milliseconds. 0 keeps the toast until removed manually. |
variant="error" also flips the toast to role="alert" /
aria-live="assertive" so screen readers interrupt to announce it.
Other variants use role="status" / aria-live="polite".
Examples
Section titled “Examples”// Successdocument.body.dispatchEvent(new CustomEvent('hc:toast', { bubbles: true, detail: { message: 'Invoice sent.' },}));
// Error, sticky until dismisseddocument.body.dispatchEvent(new CustomEvent('hc:toast', { bubbles: true, detail: { title: 'Sync failed', message: 'Could not reach the server. Retrying…', variant: 'error', duration: 0, },}));From a server-side handler:
# Djangofrom django.http import HttpResponseimport json
def delete_item(request, id): item = get_object_or_404(Item, pk=id) item.delete() return HttpResponse('', headers={ 'HX-Trigger': json.dumps({ 'hc:toast': {'message': 'Deleted.', 'variant': 'success'}, }), })Accessibility
Section titled “Accessibility”info/success/warninguserole="status"(polite) so they do not interrupt the user’s flow.errorusesrole="alert"(assertive) so failures are announced immediately. Reserve this for genuine errors.- The region itself is a labeled
regionlandmark — assistive tech can navigate to it. - Toasts disappear automatically; do not put critical information here that the user must act on. Confirmations of completed actions are the canonical use case.
Progressive enhancement
Section titled “Progressive enhancement”Without hc.behaviors.js, the hc:toast event is dispatched but no
listener exists; nothing renders. The HTTP response itself is still
valid — HX-Trigger is a no-op for plain fetch() calls.
For applications that must communicate confirmation without
JavaScript, server-render a flash message inside the page (an
hc-alert is the right
component) and remove it from the next response.
Related
Section titled “Related”- Alert — block-level inline notice; permanent until the page reloads.
- Confirm action — often paired with a toast on success.