Skip to main content

Toast Notifications

The application uses HeroUI's native Toast component for user feedback and notifications.

Overview

Toast notifications provide temporary, non-blocking feedback for user actions like:

  • Successful mutations (create, update, delete)
  • Error messages
  • Loading states
  • Informational messages

Setup

The toast system is configured in apps/web/src/main.tsx:

import { ToastProvider } from '@heroui/toast';

<ToastProvider
placement="top-right"
maxVisibleToasts={3}
toastProps={{
timeout: 4000,
hideCloseButton: false,
}}
/>;

Basic Usage

Simple Toasts

import { useToast } from '@/hooks/useToast';

function MyComponent() {
const toast = useToast();

const handleSuccess = () => {
toast.success('Guild created successfully!');
};

const handleError = () => {
toast.error('Failed to save changes', 'Please try again');
};

const handleInfo = () => {
toast.info('Processing your request...');
};

const handleWarning = () => {
toast.warning('Low disk space', 'Consider cleaning up');
};
}

RTK Query Integration

Promise-Based Toasts

For RTK Query mutations, use useToastMutations for automatic loading/success/error states:

import { useToastMutations } from '@/hooks/useToastMutations';
import { useCreateGuildMutation } from '@/store/api/guildsApi';

function CreateGuildForm() {
const [createGuild] = useCreateGuildMutation();
const { toastPromise } = useToastMutations();

const handleSubmit = async (data: GuildFormData) => {
await toastPromise(createGuild(data).unwrap(), {
loading: 'Creating guild...',
success: 'Guild created successfully!',
error: 'Failed to create guild',
});
};
}

Custom Error Handling

const { error: toastError } = useToastMutations();

try {
await updateGuild(data).unwrap();
toast.success('Guild updated!');
} catch (error) {
toastError(error, 'Failed to update guild');
}

API Reference

useToast()

Returns an object with toast methods:

  • success(title: string, description?: string) - Show success toast (green)
  • error(title: string, description?: string) - Show error toast (red)
  • info(title: string, description?: string) - Show info toast (blue)
  • warning(title: string, description?: string) - Show warning toast (yellow)
  • loading(title: string, description?: string) - Show loading toast (no auto-dismiss)
  • promise(promise, messages) - Show toast that updates based on promise state

useToastMutations()

Helper for RTK Query mutations:

  • toastPromise(promise, messages) - Automatically handles loading/success/error
  • success(message, description) - Show success toast
  • error(error, fallbackMessage) - Extract error message and show toast

Configuration

Global Settings

Configured in ToastProvider:

<ToastProvider
placement="top-right" // Toast position
maxVisibleToasts={3} // Max toasts shown at once
toastProps={{
timeout: 4000, // Auto-dismiss after 4 seconds
hideCloseButton: false, // Show close button
}}
/>

Per-Toast Settings

Use HeroUI's addToast directly for advanced options:

import { addToast } from '@heroui/toast';

addToast({
title: 'Custom toast',
description: 'With custom settings',
color: 'primary',
timeout: 0, // No auto-dismiss
hideCloseButton: true, // No close button
hideIcon: false, // Show icon
});

Best Practices

DO ✅

  • Use toasts for non-critical feedback
  • Keep messages concise (1-2 lines)
  • Use appropriate colors for context
  • Use toastPromise for mutations
  • Provide actionable error messages

DON'T ❌

  • Use toasts for critical errors (use modals instead)
  • Show multiple toasts for the same action
  • Use long messages (use description for details)
  • Rely on toasts for permanent information
  • Block user interaction with toasts

Examples

Archive Guild

const handleArchive = async (guildId: string) => {
await toastPromise(archiveGuild(guildId).unwrap(), {
loading: 'Archiving guild...',
success: 'Guild archived successfully',
error: 'Failed to archive guild',
});
};

Form Validation

const handleSubmit = async (data: FormData) => {
if (!data.name) {
toast.error('Validation failed', 'Guild name is required');
return;
}

await toastPromise(createGuild(data).unwrap(), {
loading: 'Creating guild...',
success: 'Guild created!',
error: 'Failed to create guild',
});
};

Manual Loading Control

const handleLongOperation = async () => {
const loadingToast = toast.loading('Processing...');

try {
await longOperation();
toast.dismiss(loadingToast);
toast.success('Operation complete!');
} catch (error) {
toast.dismiss(loadingToast);
toast.error('Operation failed');
}
};

Theming

Toasts automatically inherit HeroUI theme colors:

  • Success: Green (success color)
  • Error: Red (danger color)
  • Info: Blue (primary color)
  • Warning: Yellow (warning color)

Colors adapt to light/dark mode automatically via HeroUI's theme system.

Troubleshooting

Toast Not Showing

  1. Verify ToastProvider is rendered in main.tsx
  2. Check browser console for errors
  3. Ensure @heroui/toast is installed

Wrong Colors

  • Toasts use HeroUI's semantic colors
  • Check theme configuration in ThemeProvider
  • Verify HeroUI version compatibility

Toasts Stack Incorrectly

  • Check maxVisibleToasts setting
  • Verify placement prop is valid
  • Clear browser cache and restart dev server