---
title: Toast
description: Temporary notification messages backed by the solid-toaster package.
sidebar:
  order: 8
search:
  tags: [notification, message, feedback, promise]
componentKey: toast
category: overlays
upstreamHref: https://github.com/subframe7536/solid-toaster
---

# Toast

> Temporary notification messages backed by the solid-toaster package.

## Import

Install `solid-toaster`:

```bash
bun add solid-toaster
```

```bash
pnpm add solid-toaster
```

```bash
npm i solid-toaster
```

Then import styles, mount a `Toaster` instance.

```tsx
import 'solid-toaster/style.css'

import { Button } from '@subframe7536/moraine'
import { Toaster, toast } from 'solid-toaster'

export default function App() {
  return (
    <>
      <Button onClick={() => toast.success('Saved!')}>Toast</Button>
      <Toaster />
    </>
  )
}
```

## Examples

### Basic Toasts

Send status toasts to the global toaster instance, including loading to success update.

```tsx
function BasicToasts() {
  const wait = (ms: number) =>
    new Promise<void>((resolve) => {
      setTimeout(resolve, ms)
    })

  const runLoadingToast = async () => {
    const id = toast.loading('Uploading files...')
    await wait(1200)
    toast.success('Upload complete', { id })
  }

  return (
    <div class="flex flex-wrap gap-3 items-center">
      <Button onClick={() => toast('Default message', { onAutoClose: console.log })}>
        Default
      </Button>
      <Button variant="secondary" onClick={() => toast.success('Saved successfully')}>
        Success
      </Button>
      <Button variant="outline" onClick={() => toast.warning('Careful with this action')}>
        Warning
      </Button>
      <Button variant="destructive" onClick={() => toast.error('Something went wrong')}>
        Error
      </Button>
      <Button variant="ghost" onClick={runLoadingToast}>
        Loading -&gt; Success
      </Button>
    </div>
  )
}
```

### Promise + Scoped Instances

Use toast.promise for async lifecycle and route toasts by toasterId.

```tsx
function PromiseScopedInstances() {
  const [promiseRuns, setPromiseRuns] = createSignal(0)
  const wait = (ms: number) =>
    new Promise<void>((resolve) => {
      setTimeout(resolve, ms)
    })

  const runPromiseToast = () => {
    const nextRun = promiseRuns() + 1
    setPromiseRuns(nextRun)
    const request = wait(1400).then(() => ({ run: nextRun }))

    toast.promise(request, {
      loading: `Sync #${nextRun} in progress...`,
      success: (result) => `Sync #${result.run} finished`,
      error: (error) => `Sync failed: ${String(error)}`,
      duration: 1e6,
    })
  }

  return (
    <div class="flex flex-wrap gap-3 items-center">
      <Button onClick={runPromiseToast}>Run promise toast ({promiseRuns()})</Button>
      <Button
        variant="outline"
        onClick={() => toast.info('To bottom-left custom', { toasterId: 'custom' })}
      >
        Send to custom toaster
      </Button>
      <Button variant="ghost" onClick={() => toast.dismiss()}>
        Dismiss all
      </Button>
    </div>
  )
}
```

