Skip to main content

Adding the Toast Component

<CourierToast />

Courier Toast component

Toasts are short-lived notifications that notify users and prompt them to take action. Courier’s Toast component is connected to the feed of Courier Inbox messages.
Toasts are synced with the Inbox message feed. You can use both components together to provide persistent and temporary notifications in your app. See the Inbox Component section above.
Add <CourierToast /> to your app and authenticate the user with the Courier backend:
import { useEffect } from "react";
import { CourierToast, useCourier } from "@trycourier/courier-react";

export default function App() {

  const courier = useCourier();

  useEffect(() => {
    // Generate a JWT for your user on your backend server
    const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";

    // Authenticate the user
    courier.shared.signIn({
      userId: $YOUR_USER_ID,
      jwt: jwt,
    });
  }, []);

  return <CourierToast />;
}
If you’re using tenants, you can scope requests to a particular tenant by passing its ID to the signIn request.
courier.shared.signIn({
  userId: "my-user-id",
  jwt: jwt,
  tenantId: "my-tenant-id"
});
For the full reference of sign in parameters, see the Courier JS docs.
Sample App: See a complete working example in our React Toast sample app.
Some initialization for toasts is asychronous. If your app displays toasts immediately when the component is mounted, consider using the onReady to wait until the <CourierToast> component is fully initialized.

Handle Clicks

Toast Items

Callback PropType Signature
onToastItemClick(props: CourierToastItemClickEvent) => void
Pass a callback function to the onToastItemClick prop to handle clicks on toast items.
import { useEffect } from "react";
import {
  CourierToast,
  useCourier,
  type CourierToastItemClickEvent
} from "@trycourier/courier-react";

export default function App() {

  const courier = useCourier();

  useEffect(() => {
    // Generate a JWT for your user on your backend server
    const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";

    // Authenticate the user
    courier.shared.signIn({ userId, jwt });
  }, []);

  return (
    <CourierToast
      onToastItemClick={({ message }: CourierToastItemClickEvent) => {
        console.log("Toast clicked:", message);
      }},
    />
  );
}

Action Buttons

Callback PropType Signature
onToastItemActionClick(props: CourierToastItemActionClickEvent) => void

Courier Toast with action buttons

If a message contains actions, toast items will include a button for each. By default, these buttons do not implement any functionality. Use onToastItemActionClick to handle clicks on action buttons within toast items.
import { useEffect } from "react";
import {
  CourierToast,
  useCourier,
  type CourierToastItemActionClickEvent
} from "@trycourier/courier-react";

export default function App() {

  const courier = useCourier();

  useEffect(() => {
    // Generate a JWT for your user on your backend server
    const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";

    // Authenticate the user
    courier.shared.signIn({ userId, jwt });
  }, []);

  return (
    <CourierToast
      onToastItemActionClick={({ message, action }: CourierToastItemActionClickEvent) => {
        window.open(action.href);
      }}
    />
  );
}

Styles and Theming

The fastest way to style Courier Toast to match your app is with a custom theme.
You can customize fonts, icons, colors, and more. The full CourierToastTheme reference is included below.

Light and Dark Themes

Customize both the light and dark themes. The example below shows custom styling applied to toast items.

Courier Toast with a custom theme

import {
  CourierToast,
  type CourierToastTheme
} from "@trycourier/courier-react";

export default function App() {
  // Courier authentication and other component code...

  const theme: CourierToastTheme = {
    toast: {
      item: {
        title: {
          color: "#6366f1",
          weight: "bold",
        },
        backgroundColor: "#edeefc",
        border: "1px solid #cdd1ff",
        borderRadius: "15px",
      },
    },
  };

  return <CourierToast lightTheme={theme} mode="light" />;
}

CourierToastTheme

An instance of CourierToastTheme can be set as the light and dark themes respectively.

Custom Elements

Custom Content

Toast with custom item content

Render PropType Signature
renderToastItemContent(props: CourierToastItemFactoryProps) => ReactNode
Customize only the content area of each toast item while reusing the default stack structure and styling by passing a factory function to renderToastItemContent. The dismiss button and auto-dismiss functionality are still handled by the default toast item wrapper.
import {
  CourierToast,
  type CourierToastItemFactoryProps
} from "@trycourier/courier-react";

const CustomToastContent = ({ message }: CourierToastItemFactoryProps) => (
  <div style={{ padding: "16px" }}>
    <strong style={{ display: "block", marginBottom: "4px" }}>
      {message.title}
    </strong>
    <p style={{ margin: 0, fontSize: "14px", color: "#6b7280" }}>
      {message.body}
    </p>
  </div>
);

export default function App() {
  // Courier authentication and other component code...

  return (
    <CourierToast
      renderToastItemContent={(props: CourierToastItemFactoryProps) => {
        return <CustomToastContent {...props} />
      }}
    />
  );
}

Fully Custom Items

Render PropType Signature
renderToastItem(props: CourierToastItemFactoryProps) => ReactNode
Customize each toast item’s appearance and behavior completely by passing a factory function to renderToastItem. This gives you complete control over the toast item, including its container, styling, and dismiss behavior. When using renderToastItem, the autoDismiss and autoDismissTimeoutMs props are still respected, and toasts will be automatically removed after the timeout if autoDismiss is enabled.

Toast with a fully custom item

import {
  CourierToast,
  type CourierToastItemFactoryProps
} from "@trycourier/courier-react";

const CustomToastItem = ({ message, autoDismiss, autoDismissTimeoutMs, dismiss }: CourierToastItemFactoryProps) => (
  <div style={{
    display: "flex",
    alignItems: "center",
    gap: "12px",
    marginBottom: "8px"
  }}>
    <div style={{
      flex: 1,
      padding: "16px",
      background: "#f6f6fe",
      border: "1px solid #c6c2ff",
      borderRadius: "8px",
    }}>
      <strong style={{ display: "block", marginBottom: "4px" }}>
        {message.title}
      </strong>
      <p style={{ margin: 0, fontSize: "14px" }}>
        {message.body}
      </p>
    </div>

    <div style={{
      display: "flex",
      flexDirection: "column",
      gap: "8px",
      minWidth: "100px"
    }}>
      {message.actions?.map((action, index) => (
        <button
          key={index}
          onClick={() => window.open(action.href)}
          style={{
            padding: "8px 12px",
            background: "#f6f6fe",
            border: "1px solid #c6c2ff",
            borderRadius: "8px",
          }}
        >
          {action.content}
        </button>
      ))}
    </div>
  </div>
);

export default function App() {
  // Courier authentication and other component code...

  return (
    <CourierToast
      renderToastItem={(props: CourierToastItemFactoryProps) => {
        return <CustomToastItem {...props} />
      }}
    />
  );
}

CourierToast Props

The full set of React props you can pass to the <CourierToast> component.
Prop NameTypeDefaultDescription
styleCSSProperties{ position: "fixed", width: "380px", top: "30px", right: "30px", zIndex: 999 }Styles applied to the toast component. Useful for customizing position and layout.
lightThemeCourierToastThemeundefinedTheme object used when light mode is active.
darkThemeCourierToastThemeundefinedTheme object used when dark mode is active.
mode"light" | "dark" | "system""system"Manually set the theme mode.
autoDismissbooleanfalseEnable toasts to auto-dismiss with a countdown bar.
autoDismissTimeoutMsnumber5000Timeout in milliseconds before a toast auto-dismisses.
dismissButton"visible" | "hidden" | "hover" | "auto""auto"Set dismiss button visibility. "auto" shows button always if autoDismiss is false, on hover if true.
onToastItemClick(props: CourierToastItemClickEvent) => voidundefinedCallback invoked when a toast item is clicked.
onToastItemActionClick(props: CourierToastItemActionClickEvent) => voidundefinedCallback invoked when a toast item action button is clicked.
renderToastItem(props: CourierToastItemFactoryProps) => ReactNodeundefinedCustom render function for entire toast items.
renderToastItemContent(props: CourierToastItemFactoryProps) => ReactNodeundefinedCustom render function for toast item content only.
onReady(ready: boolean) => voidundefinedCallback invoked when the component is ready to receive messages.

Using auto-dismiss

Toast component with auto-dismiss enabled

Use auto-dismissed toasts for non-critical notifications that don’t require immediate action. For example, you might use an auto-dismissed toast to notify a user that a scheduled task completed without issue. Auto-dismiss details Enabling auto-dismiss changes a few bits of toasts’ default behavior:
  • Toast items are automatically removed after the specified timeout.
  • A countdown bar appears at the top of each toast to indicate the time remaining before dismissal. This countdown bar is theme-able via the autoDismissBarColor value in CourierToastTheme.
  • The dismiss button (x) is only visible on hover, but you can customize this behavior using the dismissButton prop.
import { CourierToast } from "@trycourier/courier-react";

export default function App() {
  // Courier authentication and other component code...

  return (
    <CourierToast
      autoDismiss={true}
      autoDismissTimeoutMs={7000}
    />
  );
}

Using the onReady Callback

The onReady callback is invoked when the CourierToast component has finished mounting and is ready to display messages. When to use onReady Some initialization for <CourierToast> is asychronous, such as syncing state between React and the underlying Web Components. If you’re displaying toasts immediately on page load (for example, with CourierToastDatastore) or observing issues where toasts do not properly render custom content or click handlers, consider using onReady to wait for <CourierToast> to fully initialize before acting. In the example below, onReady is used to toggle the toastReady state, passed as a dependency to the React effect that performs authentication.
import { useEffect, useState } from "react";
import {
  CourierToast,
  useCourier,
  type CourierToastItemFactoryProps
} from "@trycourier/courier-react";

const CustomToastItem = ({ message }: CourierToastItemFactoryProps) => (
  <div style={{ padding: "16px", background: "#f3f4f6", borderRadius: "8px" }}>
    <strong>{message.title}</strong>
  </div>
);

export default function App() {
  const [toastReady, setToastReady] = useState(false);
  const courier = useCourier();

  useEffect(() => {
    if (toastReady) {
      // Only authenticate after the toast is ready to ensure
      // custom render functions are applied
      const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";

      courier.shared.signIn({
        userId: $YOUR_USER_ID,
        jwt: jwt,
      });
    }
  }, [toastReady, courier]);

  return (
    <CourierToast
      onReady={setToastReady}
      renderToastItem={(props: CourierToastItemFactoryProps) => {
        return <CustomToastItem {...props} />
      }}
    />
  );
}