Overview

Lightweight, non-blocking notifications built on Radix Toast and styled with tokens. aSaaSin exposes a tiny API: a mounted <Toaster /> and a useToast() hook you can call from any client component. Supports swipe-to-dismiss, variants, and dark mode. See also shadcn/ui Toast.

Exports

From @/components/ui/Toast:

  • ToastProvider, ToastViewport (internal mounting)
  • Toast, ToastTitle, ToastDescription, ToastAction, ToastClose (low-level building blocks)
  • type ToastProps, type ToastActionElement

App-layer:

  • Toaster component - renders all active toasts (mounted once at app root)
  • useToast() hook - returns { toasts, toast, dismiss }
  • toast() function - programmatic API (returns { id, update, dismiss })

Mounting

The <Toaster /> is already mounted in AppProviders so you can call useToast() anywhere. Only one <Toaster /> should exist in the app.

Quick start

'use client';

import * as React from 'react';
import { Button } from '@/components/ui/Button';
import { useToast } from '@/hooks';

export function ToastDemo() {
  const { toast } = useToast();

  return (
    <div className="flex gap-4">
      <Button
        onClick={() =>
          toast({
            title: 'Saved',
            description: 'Your changes were stored successfully.',
            variant: 'success',
          })
        }
      >
        Success
      </Button>

      <Button
        variant="destructive"
        onClick={() =>
          toast({
            title: 'Failed',
            description: 'Something went wrong. Please try again.',
            variant: 'destructive',
          })
        }
      >
        Error
      </Button>
    </div>
  );
}

Variants

The toast style is driven by a cva with variant options: default (neutral), success, and destructive. Pass variant when creating a toast, if omitted, default is used.

Actions and dismissal

Add an optional action (button) to let users undo or open a link. Users can dismiss via the close icon, by swiping, or programmatically with dismiss(id). One toast is shown at a time (toastLimit = 1). Closed toasts are removed after a delay.

'use client';

import * as React from 'react';
import { Button } from '@/components/ui/Button';
import { ToastAction } from '@/components/ui/Toast';
import { useToast } from '@/hooks';

export function ToastWithAction() {
  const { toast } = useToast();

  return (
    <Button
      onClick={() =>
        toast({
          title: 'Item archived',
          description: 'You can undo this action.',
          action: (
            <ToastAction altText="Undo">Undo</ToastAction>
          ),
        })
      }
    >
      Archive
    </Button>
  );
}

Behavior & layout

  • Viewport - fixed, stacks toasts; mobile top-in, desktop bottom-in.
  • Gestures - swipe-to-dismiss supported out of the box.
  • Duration - uses Radix defaults; you can override per toast.
  • Accessibility - provided by Radix (ARIA live region and focus handling). Keep titles short and textual, avoid emoji-only, and make action buttons clearly labeled.

Keep toasts brief (1–2 lines). Avoid duplicating information already visible on the page. Use actions sparingly and only when the operation is reversible.