bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Default () {
const toaster = createToaster ();
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ();
</ script >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Usage
This component acts as a Singleton. Implement a single instance of <Toast.Group> in the root scope your application, then trigger it anywhere on demand using a shared createToaster() instance.
import { toaster } from '/some/path/toaster.ts' ;
import { Toast } from '@skeletonlabs/skeleton-react' ;
import type { PropsWithChildren } from 'react' ;
export default function Layout ( props : PropsWithChildren ) {
return (
<>
{props.children}
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
< script lang = "ts" >
import { toaster } from '/some/path/toaster.ts' ;
import { Toast } from '@skeletonlabs/skeleton-svelte' ;
import type { Snippet } from 'svelte' ;
interface Props {
children ?: Snippet ;
}
const props : Props = $ props ();
</ script >
{@ render props. children ?.()}
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast toast ={toast}>
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
import { toaster } from '/some/path/toaster.ts' ;
export default function Page () {
function onClickHandler () {
toaster. info ({ title: 'Example' , description: 'This is a toast message.' });
}
return ();
}
< script lang = "ts" >
import { toaster } from '/some/path/toaster.ts' ;
function onClickHandler () {
toaster. info ({ title: 'Example' , description: 'This is a toast message.' });
}
</ script >
Triggers
Shorthand methods are available for toast triggers, including: info(), success(), warning(), and error().
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Type () {
const toaster = createToaster ();
return (
<>
< div className = "grid grid-cols-2 gap-2" >
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Info' ,
description: 'This is an info toast.' ,
})
}
>
Info
</ button >
< button
className = "btn preset-filled-success-500"
onClick = {() =>
toaster. success ({
title: 'Success' ,
description: 'This is a success toast.' ,
})
}
>
Success
</ button >
< button
className = "btn preset-filled-warning-500"
onClick = {() =>
toaster. warning ({
title: 'Warning' ,
description: 'This is a warning toast.' ,
})
}
>
Warning
</ button >
< button
className = "btn preset-filled-error-500"
onClick = {() =>
toaster. error ({
title: 'Error' ,
description: 'This is an error toast.' ,
})
}
>
Error
</ button >
</ div >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
Info Success Warning Error
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ();
</ script >
< div class = "grid grid-cols-2 gap-2" >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Info' ,
description: 'This is an info toast.' ,
})}
>
Info
</ button >
< button
class = "btn preset-filled-success-500"
onclick ={() =>
toaster. success ({
title: 'Success' ,
description: 'This is a success toast.' ,
})}
>
Success
</ button >
< button
class = "btn preset-filled-warning-500"
onclick ={() =>
toaster. warning ({
title: 'Warning' ,
description: 'This is a warning toast.' ,
})}
>
Warning
</ button >
< button
class = "btn preset-filled-error-500"
onclick ={() =>
toaster. error ({
title: 'Error' ,
description: 'This is an error toast.' ,
})}
>
Error
</ button >
</ div >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Or use the generic create() method to trigger toasts of any type: info|success|warning|error.
toaster. create ({
type: 'info' ,
title: 'This is a toast' ,
description: 'This is a toast description.' ,
});
Placement
Set the placement value in your createToaster instance to define the global screen position.
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Placement () {
const toaster = createToaster ({
placement: 'bottom-end' ,
});
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ({
placement: 'bottom-end' ,
});
</ script >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Overlap
Use the overlap option in your createToaster instance to enable overlapping toasts.
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Default () {
const toaster = createToaster ({
overlap: true ,
});
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ({
overlap: true ,
});
</ script >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Note: Hovering over the toast group will expand all the toasts.
Closable
Use the closable prop to toggle display of the close button.
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Closable () {
const toaster = createToaster ();
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
closable: false ,
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
{toast.closable && < Toast.CloseTrigger />}
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ();
</ script >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
closable: false ,
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
{# if toast.closable}
< Toast . CloseTrigger />
{/ if }
</ Toast >
{/ snippet }
</ Toast . Group >
Use the meta key to pass arbitrary data along with the toast instance. This can be used to display an icon for example.
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
import { SkullIcon } from 'lucide-react' ;
export default function Meta () {
const toaster = createToaster ();
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
meta: {
icon: < SkullIcon className = "size-8" />,
},
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
{toast.meta ! .icon}
< Toast.Message >
< Toast.Title className = "flex gap-2 items-center" >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { SkullIcon } from '@lucide/svelte' ;
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ();
</ script >
{# snippet skull ()}
< SkullIcon class = "size-8" />
{/ snippet }
< button
class = "btn preset-filled"
onclick ={() =>
toaster. info ({
title: 'Title' ,
description: 'This is a description.' ,
meta: {
icon: skull,
},
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
{@ render toast.meta ! . icon ()}
< Toast . Message >
< Toast . Title class = "flex gap-2 items-center" >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description} {toast.meta?.foo}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Promise
Toasts support asynchronous updates using promises.
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Promise_ () {
const toaster = createToaster ();
function generatePositiveNumber () {
return new Promise < number >(( resolve , reject ) => {
setTimeout (() => {
const number = Math. random () - 0.5 ;
if (number > 0 ) {
resolve (number);
} else {
reject (number);
}
}, 2000 );
});
}
return (
<>
< button
className = "btn preset-filled"
onClick = {() =>
toaster. promise ( generatePositiveNumber (), {
loading: {
title: 'Loading...' ,
description: 'Please wait while generating your number' ,
},
success : ( number ) => ({
title: 'Success' ,
description: `Your number is ${ number . toFixed ( 2 )}` ,
}),
error : ( number ) => ({
title: 'Error' ,
description: `Your number is ${( number as number ). toFixed ( 2 )}` ,
}),
})
}
>
Toast
</ button >
< Toast.Group toaster = {toaster}>
{( toast ) => (
< Toast toast = {toast} key = {toast.id}>
< Toast.Message >
< Toast.Title >{toast.title}</ Toast.Title >
< Toast.Description >{toast.description}</ Toast.Description >
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
)}
</ Toast.Group >
</>
);
}
bg-surface-50-950 preset-filled-primary-500 preset-filled-secondary-500 preset-filled-tertiary-500 preset-filled-success-500 preset-filled-warning-500 preset-filled-error-500 preset-filled-surface-500 bg-linear-to-br from-primary-500 to-secondary-500 bg-linear-to-br from-secondary-500 to-tertiary-500 bg-linear-to-br from-tertiary-500 to-primary-500
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
const toaster = createToaster ();
function generatePositiveNumber () {
return new Promise < number >(( resolve , reject ) => {
setTimeout (() => {
const number = Math. random () - 0.5 ;
if (number > 0 ) {
resolve (number);
} else {
reject (number);
}
}, 2000 );
});
}
</ script >
< button
class = "btn preset-filled"
onclick ={() =>
toaster. promise ( generatePositiveNumber (), {
loading: {
title: 'Loading...' ,
description: 'Please wait while generating your number' ,
},
success : ( number ) => ({
title: 'Success' ,
description: `Your number is ${ number }` ,
}),
error : ( number ) => ({
title: 'Error' ,
description: `Your number is ${ number }` ,
}),
})}
>
Toast
</ button >
< Toast . Group { toaster } >
{# snippet children (toast)}
< Toast { toast } >
< Toast . Message >
< Toast . Title >{toast.title}</ Toast . Title >
< Toast . Description >{toast.description}</ Toast . Description >
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
{/ snippet }
</ Toast . Group >
Anatomy
Here’s an overview of how the Toast component is structured in code:
import { Toast, createToaster } from '@skeletonlabs/skeleton-react' ;
export default function Anatomy () {
return (
< Toast.Group >
< Toast >
< Toast.Message >
< Toast.Title />
< Toast.Description />
</ Toast.Message >
< Toast.CloseTrigger />
</ Toast >
</ Toast.Group >
);
}
< script lang = "ts" >
import { Toast, createToaster } from '@skeletonlabs/skeleton-svelte' ;
</ script >
< Toast . Group >
< Toast >
< Toast . Message >
< Toast . Title />
< Toast . Description />
</ Toast . Message >
< Toast . CloseTrigger />
</ Toast >
</ Toast . Group >
API Reference
Unable to load component information for react/toast
Unable to load component information for svelte/toast