toast()
Create toasts from anywhere — event handlers, tasks, plain modules. The store is global, so no context or hook is needed; the <Toaster /> picks them up.
toast(message, options?) // neutral toast
toast.message(message, options?) // alias of toast()
toast.success(message, options?)
toast.info(message, options?)
toast.warning(message, options?)
toast.error(message, options?)
toast.loading(message, options?) // spinner, never auto-closes
toast.promise(promise, data) // loading → success / error
toast.custom((id) => jsx, options?)
toast.dismiss(id?) // one toast, or all of them
toast.getToasts() // active toasts
toast.getHistory() // created so far (up to 100)message is a string, JSX, or a function returning either. Every helper takes the same options object as its last argument.
Types
toast("Event has been created");
toast("Event has been created", {
description: "Monday, January 3rd at 6:00pm",
});
toast.success("Event has been created");
toast.info("Be at the area 10 minutes before the event time");
toast.warning("Event start time cannot be earlier than 8am");
toast.error("Event has not been created");
toast.loading("Creating event…");toast.loading() has no timer: update it (see below) or dismiss it when the work is done.
Action and cancel
Add a primary action and/or a secondary cancel button. Handlers are QRLs. The toast closes after the click unless the action sets preventDefault: true — Qwik's take on sonner's event.preventDefault().
import { $ } from "@qwik.dev/core";
toast("Event has been created", {
action: {
label: "Undo",
onClick$: $(() => toast.success("Change reverted")),
// preventDefault: true, // keep the toast open after the click
},
cancel: {
label: "Cancel",
onClick$: $(() => console.log("Cancelled")),
},
});Instead of an Action object you can pass any JSX as action or cancel; it renders as-is.
Promise
toast.promise() shows a loading toast and turns it into a success or error toast when the promise settles. Pass a promise, or a function / QRL returning one.
import { $ } from "@qwik.dev/core";
const createEvent = $(
() => new Promise<{ name: string }>((resolve) =>
setTimeout(() => resolve({ name: "Sonner" }), 2000),
),
);
const result = toast.promise(createEvent, {
loading: "Creating event…",
success: $((data: { name: string }) => `${data.name} has been created`),
error: "Could not create the event",
finally: $(() => console.log("settled")),
});
// Await the original value (or rejection) after the toast updates.
const data = await result.unwrap();| Field | Type | Default |
|---|---|---|
loading | string | JSXOutput | — |
| Message of the loading toast. Without it no toast is shown until the promise settles. | ||
success | string | JSXOutput | QRL<(data) => …> | ExtendedResult | — |
Shown when the promise resolves. Functions receive the resolved value and may return a message or { message, ...options }. | ||
error | string | JSXOutput | QRL<(error) => …> | ExtendedResult | — |
Shown when the promise rejects, resolves to an Error, or resolves to a Response with ok: false (the function then receives HTTP error! status: <code>). | ||
description | string | JSXOutput | QRL<(data) => …> | — |
| Description for the settled toast. A plain value is also shown while loading; a function runs once settled. | ||
finally | QRL<() => void | Promise<void>> | — |
| Runs after the promise settles, whatever the outcome. | ||
…options | ExternalToast | — |
Any toast option (except description, above) — applied to the loading toast. | ||
Changing options on settle
Return an object with a message to change the settled toast's options too:
toast.promise(save, {
loading: "Saving…",
// Return { message, ...options } to also change the toast's options.
success: $((data: Doc) => ({
message: "Saved",
description: `${data.title} is up to date`,
action: { label: "View", onClick$: $(() => open(data.url)) },
})),
error: $((err: Error) => err.message),
});Custom JSX
Pass JSX as the message to keep the default look, or use toast.custom() to render only your own markup — it drops the default toast styles but keeps stacking, swiping and timers.
// JSX as the message keeps the default toast styling
toast(<span>Signed in as <strong>diecodev</strong></span>);
// toast.custom renders only your markup; the callback receives the id
toast.custom(
(id) => (
<div class="my-toast">
<strong>You've unlocked Pro</strong>
<button onClick$={() => toast.dismiss(id)}>Dismiss</button>
</div>
),
{ duration: Number.POSITIVE_INFINITY },
);Updating a toast
Call any helper with the id of an existing toast to update it in place.
const id = toast.loading("Uploading…");
// Same id → the toast updates in place, keeping its position in the stack
toast.success("Upload complete", { id });Dismissing
const id = toast("Event has been created");
toast.dismiss(id); // remove one toast
toast.dismiss(); // remove every toastUse onDismiss$ and onAutoClose$ to react to a toast closing — see callbacks.
Reading state
toast.getToasts(); // toasts currently on screen (not dismissed)
toast.getHistory(); // toasts created so far, dismissed ones included (up to 100)For a reactive list inside a component use useSonner().
Return values
| Call | Type | Default |
|---|---|---|
toast(), .success(), … | string | number | — |
The toast id — the one you passed as id, or an auto-incremented number. | ||
toast.custom() | string | number | — |
| The toast id; also passed to your render callback. | ||
toast.promise() | (string | number) & { unwrap } | — |
The id with an unwrap() method that resolves/rejects like the original promise. Without loading only { unwrap } is returned; without a second argument, undefined. | ||
toast.dismiss() | string | number | undefined | — |
| The id you passed, if any. | ||