---
title: Basic Toast
description: A simple toast notification component with a link action and theme customization
---

```tsx
'use client';

import { BasicToast } from '@/ui/BasicToast';
import { type ToasterProps, Toaster, toast } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/BasicToast.config';

export function BasicToastDemo() {
  const showToast = () => {
    toast.custom(
      (t) => (
        <BasicToast
          title="Get 10% off your first order"
          incentive="Click here"
          href="#"
          theme="dark"
          isVisible={t.visible}
          labels={{ close: 'Close' }}
          onClose={() => toast.dismiss(t.id)}
        >
          Sign up for our newsletter and get 10% off your first order
        </BasicToast>
      ),
      { duration: 10000 },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}
```

## Installation

Using the CLI:

```bash
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/basic-toast.json
```

Or manually, copy the following code into `/ui/BasicToast.tsx`:

```tsx
'use client';
import clsx from 'clsx';
import { type ComponentPropsWithoutRef, type PropsWithChildren, useId } from 'react';

import { Icon, type IconicNames } from '@clubmed/trident-icons';
import { getBgColor, getComplementaryTextColor, getThemeColor } from './helpers/colors/colors';
import { Link } from './Link';
import type { Theme } from './types/Theme';

export interface BasicToastProps extends ComponentPropsWithoutRef<'div'> {
  /**
   * @deprecated use children slot instead
   */
  description?: string;
  href: string;
  icon?: IconicNames;
  incentive: string;
  isVisible: boolean;
  labels: { close: string };
  onClick?: () => void;
  onClose?: () => void;
  theme: Theme;
  title: string;
}

export function BasicToast({
  className,
  description,
  href,
  icon,
  incentive,
  isVisible,
  labels,
  onClick,
  onClose,
  theme = 'dark',
  title,
  children,
  ...attrs
}: PropsWithChildren<BasicToastProps>) {
  const color = getThemeColor(theme);
  const id = useId();
  const content = children ?? description;

  return (
    <div
      {...attrs}
      className={clsx(
        isVisible ? 'animate-slide-right-enter' : 'animate-slide-right-exit opacity-0',
        'relative isolate flex gap-x-20 rounded-16 p-20 transition-opacity duration-300',
        getBgColor(color),
        getComplementaryTextColor(color),
        className,
      )}
      role="note"
    >
      {icon && <Icon name={icon} width="30px" />}
      <a
        className="group pe-44 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 rounded-pill"
        href={href}
        onClick={onClick}
      >
        <p className="mb-4 text-b3 font-bold" id={id}>
          {title}
        </p>
        {content && <div className="mb-12 text-b4">{content}</div>}
        <Link component="span" className="text-b3 font-bold" label={incentive} />
      </a>
      {onClose && (
        <button
          aria-describedby={id}
          aria-label={labels.close}
          className={clsx(
            'absolute end-0 top-0 m-20 outline-none focus-visible:ring-4 focus-visible:ring-black focus-visible:ring-offset-2 rounded-pill',
            getComplementaryTextColor(color),
          )}
          onClick={onClose}
        >
          <Icon name="CrossDefault" width="24px" />
        </button>
      )}
    </div>
  );
}
```

## Usage

```tsx showLineNumbers
import { BasicToast } from '@/ui/BasicToast';
import { toast } from 'react-hot-toast';

export function Component() {
  const showToast = () => {
    toast.custom(
      (t) => (
        <BasicToast
          title="Get 10% off your first order"
          incentive="Click here"
          href="#"
          theme="dark"
          isVisible={t.visible}
          labels={{ close: 'Close' }}
          onClose={() => toast.dismiss(t.id)}
        >
          Sign up for our newsletter and get 10% off your first order
        </BasicToast>
      ),
      { duration: 10000 }
    );
  };

  return <button onClick={showToast}>Show Toast</button>;
}
```

## API Reference

### BasicToast

| Prop          | Type            | Default     | Description                                                  |
| ------------- | --------------- | ----------- | ------------------------------------------------------------ |
| `title`       | `string`        | required    | The main heading text of the toast                           |
| `children`    | `ReactNode`     | `undefined` | Main body content (preferred)                                |
| `description` | `string`        | `undefined` | Deprecated fallback body text when `children` is not passed  |
| `incentive`   | `string`        | required    | The call-to-action link text                                 |
| `href`        | `string`        | required    | The URL for the call-to-action link                          |
| `theme`       | `Theme`         | `"dark"`    | The color theme of the toast (affects background color)      |
| `isVisible`   | `boolean`       | required    | Controls the visibility state and animation of the toast     |
| `labels`      | `{ close }`     | required    | Accessibility label for the close button                     |
| `icon`        | `IconicNames`   | `undefined` | Optional icon name from the Trident Icons library            |
| `onClick`     | `() => void`    | `undefined` | Callback function when the link is clicked                   |
| `onClose`     | `() => void`    | `undefined` | Callback function when the close button is clicked           |

## Examples

### Dark Theme

```tsx
'use client';

import { BasicToast } from '@/ui/BasicToast';
import { type ToasterProps, Toaster, toast } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/BasicToast.config';

export function BasicToastDemo() {
  const showToast = () => {
    toast.custom(
      (t) => (
        <BasicToast
          title="Get 10% off your first order"
          incentive="Click here"
          href="#"
          theme="dark"
          isVisible={t.visible}
          labels={{ close: 'Close' }}
          onClose={() => toast.dismiss(t.id)}
        >
          Sign up for our newsletter and get 10% off your first order
        </BasicToast>
      ),
      { duration: 10000 },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}
```

### Saffron Theme

```tsx
'use client';

import { BasicToast } from '@/ui/BasicToast';
import { type ToasterProps, Toaster, toast } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/BasicToast.config';

export function BasicToastSaffronDemo() {
  const showToast = () => {
    toast.custom(
      (t) => (
        <BasicToast
          title="Get 10% off your first order"
          incentive="Click here"
          href="#"
          theme="saffron"
          isVisible={t.visible}
          labels={{ close: 'Close' }}
          onClose={() => toast.dismiss(t.id)}
        >
          Sign up for our newsletter and get 10% off your first order
        </BasicToast>
      ),
      { duration: 10000 },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}
```

### With Icon

```tsx
'use client';

import { BasicToast } from '@/ui/BasicToast';
import { type ToasterProps, Toaster, toast } from 'react-hot-toast';
import { getHotToastConfig } from '@/ui/BasicToast.config';

export function BasicToastWithIconDemo() {
  const showToast = () => {
    toast.custom(
      (t) => (
        <BasicToast
          title="Get 10% off your first order"
          incentive="Click here"
          href="#"
          theme="dark"
          icon="Trident"
          isVisible={t.visible}
          labels={{ close: 'Close' }}
          onClose={() => toast.dismiss(t.id)}
        >
          Sign up for our newsletter and get 10% off your first order
        </BasicToast>
      ),
      { duration: 10000 },
    );
  };

  return (
    <>
      <Toaster {...(getHotToastConfig() as ToasterProps)} />
      <button onClick={showToast}>Show Toast</button>
    </>
  );
}
```

## Notes

- The toast is designed to display promotional or informational messages with a single action link
- The entire toast content acts as a clickable link (except for the close button)
- The component uses `react-hot-toast` for toast management
- The theme prop supports all Trident theme colors and determines the toast's background color
- The `Link` component from the Trident library is used for the incentive text styling
- Prefer `children` for body content in new code and examples
- `description` is still supported for backward compatibility
