Use the useToast hook to show toasts. Call toast.show() with a message to display a temporary notification.
function BasicToastExample() {
const toast = useToast();
return <Button onClick={() => toast.show('Copied to clipboard')}>Show Toast</Button>;
}
Actions
Add an action button to the toast for quick user actions like "Undo" or "View".
function ToastWithActionExample() {
const toast = useToast();
const handleAction = useCallback(() => {
toast.show('Message sent', {
action: {
label: 'Undo',
onPress: () => console.log('Undo pressed'),
},
});
}, [toast]);
return <Button onClick={handleAction}>Send Message</Button>;
}
Hide the close button when you want a cleaner appearance or when the toast should only be dismissed via the action or timeout.
function ToastWithoutCloseExample() {
const toast = useToast();
const handleAction = useCallback(() => {
toast.show('Item deleted', {
action: {
label: 'Undo',
onPress: () => console.log('Restored'),
},
hideCloseButton: true,
});
}, [toast]);
return <Button onClick={handleAction}>Delete Item</Button>;
}
Duration
Toast duration is automatically calculated based on content length:
- Base duration: 5 seconds
- With action: +2 seconds
- Long text (>50 characters): +0.3s per 10 additional characters
You can override the automatic calculation by providing a custom duration in milliseconds.
function CustomDurationExample() {
const toast = useToast();
return (
<HStack gap={2}>
<Button onClick={() => toast.show('Quick message', { duration: 2000 })}>Short (2s)</Button>
<Button onClick={() => toast.show('This message stays longer', { duration: 10000 })}>
Long (10s)
</Button>
</HStack>
);
}
Positioning
Use bottomOffset to adjust the vertical position of the toast. This is useful when you have bottom navigation or other fixed elements.
function BottomOffsetExample() {
const toast = useToast();
return (
<HStack gap={2}>
<Button onClick={() => toast.show('Default position')}>Default</Button>
<Button onClick={() => toast.show('Higher position', { bottomOffset: 100 })}>
With Offset (100px)
</Button>
</HStack>
);
}
Styling
Variants
Use the variant prop to change the color surge effect on the toast background. This helps communicate the nature of the notification.
function VariantExample() {
const toast = useToast();
return (
<HStack gap={2} flexWrap="wrap">
<Button onClick={() => toast.show('Default toast')}>Default</Button>
<Button onClick={() => toast.show('Success!', { variant: 'bgPositive' })}>Positive</Button>
<Button onClick={() => toast.show('Error occurred', { variant: 'bgNegative' })}>
Negative
</Button>
<Button onClick={() => toast.show('Warning', { variant: 'bgWarning' })}>Warning</Button>
</HStack>
);
}
Lifecycle Callbacks
Use onWillHide and onDidHide to respond to toast dismissal. This is useful for cleanup or triggering subsequent actions.
function LifecycleCallbacksExample() {
const toast = useToast();
const [status, setStatus] = useState('Ready');
const handleShow = useCallback(() => {
setStatus('Toast visible');
toast.show('Saving changes...', {
onWillHide: () => setStatus('Toast hiding...'),
onDidHide: () => setStatus('Toast hidden'),
});
}, [toast]);
return (
<VStack gap={2} alignItems="flex-start">
<Text font="label2">Status: {status}</Text>
<Button onClick={handleShow}>Show Toast</Button>
</VStack>
);
}
Programmatic Control
Hiding Toasts
Use toast.hide() to programmatically dismiss the current toast.
function HideToastExample() {
const toast = useToast();
const showLongToast = useCallback(() => {
toast.show('This toast will stay until dismissed', { duration: 30000 });
}, [toast]);
return (
<HStack gap={2}>
<Button onClick={showLongToast}>Show Long Toast</Button>
<Button variant="secondary" onClick={() => toast.hide()}>
Hide Toast
</Button>
</HStack>
);
}
Clearing the Queue
When multiple toasts are triggered, they queue up. Use toast.clearQueue() to remove all pending toasts.
function ClearQueueExample() {
const toast = useToast();
const showMultiple = useCallback(() => {
toast.show('First toast');
toast.show('Second toast');
toast.show('Third toast');
}, [toast]);
return (
<HStack gap={2}>
<Button onClick={showMultiple}>Queue 3 Toasts</Button>
<Button variant="secondary" onClick={() => toast.clearQueue()}>
Clear Queue
</Button>
</HStack>
);
}
Accessibility
Toast uses role="alert" for screen reader announcements. On web, the toast persists when the user hovers over it, giving them time to read the content.
For internationalization, you can customize the close button's accessibility label:
function AccessibilityExample() {
const toast = useToast();
const handleShow = useCallback(() => {
toast.show('Configuración guardada', {
closeButtonAccessibilityProps: {
accessibilityLabel: 'cerrar',
},
});
}, [toast]);
return <Button onClick={handleShow}>Mostrar Toast (Spanish)</Button>;
}
Composed Examples
A common pattern is showing toast feedback after form actions.
function FormSubmissionExample() {
const toast = useToast();
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = useCallback(async () => {
setIsSubmitting(true);
await new Promise((resolve) => setTimeout(resolve, 1000));
setIsSubmitting(false);
toast.show('Profile updated successfully', {
variant: 'bgPositive',
action: {
label: 'View',
onPress: () => console.log('Navigate to profile'),
},
});
}, [toast]);
return (
<VStack gap={3} alignItems="flex-start">
<TextInput label="Display name" placeholder="Enter your name" />
<Button onClick={handleSubmit} disabled={isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save Changes'}
</Button>
</VStack>
);
}
Clipboard Copy
Provide feedback when copying content to the clipboard.
function ClipboardCopyExample() {
const toast = useToast();
const walletAddress = '0x1234...5678';
const handleCopy = useCallback(async () => {
try {
await navigator.clipboard.writeText('0x1234567890abcdef1234567890abcdef12345678');
toast.show('Address copied to clipboard');
} catch (err) {
toast.show('Failed to copy', { variant: 'bgNegative' });
}
}, [toast]);
return (
<HStack gap={2} alignItems="center">
<Text font="mono">{walletAddress}</Text>
<IconButton name="copy" onClick={handleCopy} accessibilityLabel="Copy address" />
</HStack>
);
}
Undo Delete Action
Implement an undo pattern for destructive actions.
function UndoDeleteExample() {
const toast = useToast();
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const deletedItemRef = useRef(null);
const handleDelete = useCallback(
(index) => {
const deletedItem = items[index];
deletedItemRef.current = { item: deletedItem, index };
setItems((prev) => prev.filter((_, i) => i !== index));
toast.show(`"${deletedItem}" deleted`, {
variant: 'bgNegative',
action: {
label: 'Undo',
onPress: () => {
if (deletedItemRef.current) {
setItems((prev) => {
const newItems = [...prev];
newItems.splice(deletedItemRef.current.index, 0, deletedItemRef.current.item);
return newItems;
});
deletedItemRef.current = null;
}
},
},
});
},
[items, toast],
);
return (
<VStack gap={2} alignItems="flex-start">
{items.map((item, index) => (
<HStack key={item} gap={2} alignItems="center">
<Text font="body">{item}</Text>
<IconButton
name="trashCan"
variant="foregroundMuted"
onClick={() => handleDelete(index)}
accessibilityLabel={`Delete ${item}`}
/>
</HStack>
))}
{items.length === 0 && (
<Text font="body" color="foregroundMuted">
No items
</Text>
)}
</VStack>
);
}