Usage#
import { Toast } from '@primereact/ui/toast';
import { Toaster, toast } from '@primereact/ui/toaster';<Toaster.Root>
<Toaster.Portal>
<Toaster.Region>
{({ toaster }) =>
toaster?.toasts?.map((t) => (
<Toast.Root key={t.id} toast={t}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
<Toast.Action />
</Toast.Message>
<Toast.Close />
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>Trigger toasts from anywhere with toast(...) or one of the severity shortcuts (toast.success, toast.info, toast.warn, toast.error, toast.secondary, toast.contrast).
Examples#
Severity#
Six built-in severities: info, success, warn, error, secondary, contrast. Pass severity directly or use the shortcut method.
toast({ severity: 'success', title: 'Saved' });
toast.success({ title: 'Saved' });'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function SeverityToast() {
return (
<Toaster.Root group="severity">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Icon match="secondary">
<InfoCircle />
</Toast.Icon>
<Toast.Icon match="contrast">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function SeverityDemo() {
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button
onClick={() =>
toast.info({
title: 'Heads up',
description: 'There’s something you might want to check.',
group: 'severity'
})
}
variant="outlined"
severity="info"
>
Info
</Button>
<Button
onClick={() =>
toast.success({
title: 'Saved successfully',
description: 'Your changes have been saved.',
group: 'severity'
})
}
variant="outlined"
severity="success"
>
Success
</Button>
<Button
onClick={() =>
toast.warn({
title: 'Check this',
description: 'Some fields may need your attention.',
group: 'severity'
})
}
variant="outlined"
severity="warn"
>
Warn
</Button>
<Button
onClick={() =>
toast.error({
title: 'Something went wrong',
description: 'We couldn’t complete the action. Please try again.',
group: 'severity'
})
}
variant="outlined"
severity="danger"
>
Error
</Button>
<Button
onClick={() =>
toast.secondary({
title: 'For your information',
description: 'This is a secondary toast message.',
group: 'severity'
})
}
variant="outlined"
severity="secondary"
>
Secondary
</Button>
<Button
onClick={() =>
toast.contrast({
title: 'High contrast',
description: 'This is a contrast toast message.',
group: 'severity'
})
}
variant="outlined"
severity="contrast"
>
Contrast
</Button>
<SeverityToast />
</div>
);
}
export default SeverityDemo;
Promise#
toast.promise ties a toast to a promise, show a loading state, then transition to success or error based on the outcome.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Spinner } from '@primeicons/react/spinner';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function PromiseToast() {
return (
<Toaster.Root group="promise">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon />
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function PromiseDemo() {
function handleToastPromise() {
function fakeApiCall(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
const random = Math.random();
if (random < 0.5) {
resolve('Success!');
} else {
reject(new Error('Something went wrong'));
}
}, 2000);
});
}
toast.promise(fakeApiCall(), {
loading: {
title: 'Please wait...',
description: 'Your request is being processed. This may take a moment.',
icon: <Spinner className="animate-spin" />,
group: 'promise'
},
success: (result) => ({
title: 'Success!',
description: `${result}. Everything went smoothly. Thank you for your patience.`,
group: 'promise'
}),
error: (error: unknown) => ({
title: 'Oops, something went wrong',
description: `Error: ${error instanceof Error ? error.message : 'Unknown error'}. Please try again or contact support if the problem persists.`,
group: 'promise'
})
});
}
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={handleToastPromise} variant="outlined">
Run promise
</Button>
<PromiseToast />
</div>
);
}
export default PromiseDemo;
Update#
toast.update(id, options) merges new options into an existing toast, useful for turning a loading toast into a result.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function UpdateToast() {
return (
<Toaster.Root group="update">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function UpdateDemo() {
const handleUpdateToast = () => {
const id = toast({
loading: true,
title: 'Loading…',
description: 'Please wait while we process your request.',
group: 'update'
});
setTimeout(() => {
toast.update(id, {
severity: 'success',
loading: false,
title: 'Completed',
description: 'Your request has been processed successfully.'
});
}, 2000);
};
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={handleUpdateToast} variant="outlined">
Update toast
</Button>
<UpdateToast />
</div>
);
}
export default UpdateDemo;
Sticky#
Pass duration: Infinity to keep a toast open until it is dismissed manually. To make every toast sticky by default, set the timeout prop on Toaster to Infinity instead of per toast.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function StickyToast() {
return (
<Toaster.Root group="sticky">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function StickyDemo() {
const handleCreate = () => {
toast({
severity: 'info',
title: 'Sticky toast',
description: 'This toast stays until you dismiss it manually.',
group: 'sticky',
duration: Infinity
});
};
const handleDismiss = () => {
toast.dismiss();
};
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={handleCreate} variant="outlined">
Create toast
</Button>
<Button onClick={handleDismiss} variant="outlined" severity="secondary">
Dismiss toast
</Button>
<StickyToast />
</div>
);
}
export default StickyDemo;
Custom#
Pass render to replace the default body with custom JSX. The root wrapper (positioning, animation, swipe) is preserved.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function CustomToast() {
return (
<Toaster.Root group="custom">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast} className={toast.data?.className as string | undefined}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function CustomDemo() {
function handleCustomToast() {
const id = toast({
group: 'custom',
data: { className: 'bg-surface-0! dark:bg-surface-900! border-surface!' },
render: (
<div className="space-y-2 p-3">
<div>
<h1 className="text-sm font-medium text-surface-900 dark:text-surface-0 leading-6">
Purchase complete!{' '}
<a href="/orders/123" className="underline! hover:opacity-75">
View receipt
</a>
</h1>
<p className="text-surface-500 mt-1 text-sm">
Your order is being processed. Track all orders or{' '}
<a href="/support/returns" className="underline! hover:opacity-75">
learn about returns
</a>
</p>
</div>
<div className="flex items-center mt-3 gap-2">
<button
onClick={() => toast.dismiss(id)}
className="font-medium px-2 py-1.5 text-xs rounded-md border border-surface-200 dark:border-surface-700 hover:bg-surface-50 active:bg-surface-100 dark:hover:bg-surface-800 dark:active:bg-surface-700 text-surface-500 dark:text-surface-400"
>
Dismiss
</button>
<button
onClick={() => toast.dismiss(id)}
className="font-medium px-2 py-1.5 text-xs rounded-md border border-indigo-500/25 bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-950/75 dark:hover:bg-indigo-950 text-indigo-500 dark:text-indigo-400"
>
Track all orders
</button>
</div>
</div>
)
});
}
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={handleCustomToast} variant="outlined">
Custom toast
</Button>
<CustomToast />
</div>
);
}
export default CustomDemo;
Position#
Use the position prop on <Toaster.Root> to control where toasts appear.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function PositionToast({
position = 'bottom-right'
}: {
position: 'top-left' | 'top-right' | 'top-center' | 'bottom-left' | 'bottom-right' | 'bottom-center' | 'center';
}) {
return (
<Toaster.Root position={position} group={position}>
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
<Toast.Action as={Button} size="small" className="mt-3" />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function PositionDemo() {
const createToast = (group: string) => {
toast({
title: 'Successfully completed',
description: 'The task was completed successfully. You can now view the details.',
group
});
};
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={() => createToast('top-left')} variant="outlined">
Top Left
</Button>
<Button onClick={() => createToast('top-center')} variant="outlined">
Top Center
</Button>
<Button onClick={() => createToast('top-right')} variant="outlined">
Top Right
</Button>
<Button onClick={() => createToast('bottom-left')} variant="outlined">
Bottom Left
</Button>
<Button onClick={() => createToast('bottom-center')} variant="outlined">
Bottom Center
</Button>
<Button onClick={() => createToast('bottom-right')} variant="outlined">
Bottom Right
</Button>
<Button onClick={() => createToast('center')} variant="outlined">
Center
</Button>
<PositionToast position="top-left" />
<PositionToast position="top-right" />
<PositionToast position="top-center" />
<PositionToast position="bottom-left" />
<PositionToast position="bottom-right" />
<PositionToast position="bottom-center" />
<PositionToast position="center" />
</div>
);
}
export default PositionDemo;
Expanded Mode#
mode="expanded" always renders the stack expanded; the default stacks toasts collapsed and expands on hover.
'use client';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { toast, Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function ExpandedModeToast() {
return (
<Toaster.Root mode="expanded" limit={7} group="expanded-mode">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
<Toast.Action as={Button} size="small" className="mt-3" />
</Toast.Message>
<Toast.Close>
<Times />
</Toast.Close>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function ExpandedModeDemo() {
const createToast = () => {
toast({
title: 'Successfully completed',
description: 'The task was completed successfully. You can now view the details.',
group: 'expanded-mode'
});
};
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={createToast} variant="outlined">
Create toast
</Button>
<ExpandedModeToast />
</div>
);
}
export default ExpandedModeDemo;
Action#
Add an interactive button to the toast with the action field.
'use client';
import { Camera } from '@primeicons/react/camera';
import { Check } from '@primeicons/react/check';
import { ExclamationTriangle } from '@primeicons/react/exclamation-triangle';
import { InfoCircle } from '@primeicons/react/info-circle';
import { Times } from '@primeicons/react/times';
import { toast } from '@primereact/ui/toaster';
import { Button } from '@primereact/ui/button';
import { Toast } from '@primereact/ui/toast';
import { Toaster } from '@primereact/ui/toaster';
import { ToasterRegionInstance, ToastType } from '@primereact/ui/toaster';
function ActionToast() {
return (
<Toaster.Root group="action">
<Toaster.Portal>
<Toaster.Region>
{({ toaster }: ToasterRegionInstance) =>
toaster?.toasts.map((toast: ToastType) => (
<Toast.Root key={toast.id} toast={toast}>
<Toast.Content>
<Toast.Icon match="success">
<Check />
</Toast.Icon>
<Toast.Icon match="error">
<Times />
</Toast.Icon>
<Toast.Icon match="warn">
<ExclamationTriangle />
</Toast.Icon>
<Toast.Icon match="info">
<InfoCircle />
</Toast.Icon>
<Toast.Message>
<Toast.Title />
<Toast.Description />
<Toast.Action as={Button} size="small" className="mt-3" />
</Toast.Message>
</Toast.Content>
</Toast.Root>
))
}
</Toaster.Region>
</Toaster.Portal>
</Toaster.Root>
);
}
function ActionDemo() {
const handleCreateToast = () => {
const id = toast({
title: 'Allow camera access',
description: 'We need access to your camera to scan QR codes.',
icon: <Camera />,
group: 'action',
action: {
children: 'Enable camera',
onClick: () => {
toast.dismiss(id);
toast({
severity: 'success',
title: 'Camera access granted',
description: 'You can now scan QR codes.',
group: 'action'
});
}
}
});
};
return (
<div className="flex flex-wrap items-center justify-center gap-4">
<Button onClick={handleCreateToast} variant="outlined">
Create toast with action
</Button>
<ActionToast />
</div>
);
}
export default ActionDemo;
toast function#
toast(options) queues a toast and returns its id.
const id = toast({ severity: 'success', title: 'Saved' });Severity shortcuts#
Each severity has a shortcut that sets severity automatically:
toast.success({ title: 'Saved' });
toast.info({ title: 'Heads up' });
toast.warn({ title: 'Check this' });
toast.error({ title: 'Failed' });
toast.secondary({ title: '...' });
toast.contrast({ title: '...' });Methods#
toast.dismiss(id); // dismiss specific toast
toast.dismiss(); // dismiss all
toast.update(id, options); // merge options into existing toast
toast.promise(p, { loading, success, error });Toast options#
Any of these fields can be passed to toast(...) or its shortcuts.
| Field | Type | Description |
|---|---|---|
severity | 'info' | 'success' | 'warn' | 'error' | 'secondary' | 'contrast' | Visual severity. Defaults to info. |
title | ReactNode | Main heading. |
description | ReactNode | Secondary text. |
icon | ReactNode | Custom icon, overrides the matched <Toast.Icon match="..." /> for this toast. |
action | ButtonProps | Props forwarded to <Toast.Action> (e.g. children, onClick). |
render | ReactElement | Replaces the default body with custom JSX. |
duration | number | Auto-dismiss delay in ms. Pass Infinity to keep open. |
loading | boolean | Marks the toast as loading and disables auto-dismiss. |
dismissible | boolean | If false, hides the close button and disables swipe-to-dismiss. |
group | string | Scopes the toast to a specific <Toaster.Root group="..." />. |
data | Record<string, unknown> | Arbitrary metadata, available on the toast object and in callbacks. |
onDismiss | (toast) => void | Called when dismissed by user (close button, swipe, or dismiss(id)). |
onTimeout | (toast) => void | Called when duration elapses. |
Related#
Sub-Components#
See Toast Primitive API for the full sub-component API reference.
Hooks#
See Toast Headless API for the hook API reference.
Accessibility#
See Toast Primitive for WAI-ARIA compliance details and keyboard support.