Migrate Toast from Polaris React
The Toast API replaces the Polaris React Toast component. Both display brief, non-blocking feedback, but the Toast API is imperative: call shopify.toast.show() when an operation finishes instead of rendering a component from state.
Anchor to Migrate a toastMigrate a toast
The following example removes the Toast component, the state that controls whether it is mounted, and the Frame that hosts it. The success and error messages move into the operation that produces each result.
Migrating a save notification
Polaris web components
function SaveProduct({onSave}: {onSave: () => Promise<void>}) {
async function handleSave() {
try {
await onSave();
shopify.toast.show('Product saved', {duration: 5000});
} catch {
shopify.toast.show("Product couldn't be saved", {isError: true});
}
}
return <s-button onClick={handleSave}>Save product</s-button>;
}Polaris React
import {Button, Frame, Toast} from '@shopify/polaris';
import {useState} from 'react';
export function SaveProduct({onSave}: {onSave: () => Promise<void>}) {
const [toast, setToast] = useState<{
content: string;
error?: boolean;
} | null>(null);
async function handleSave() {
try {
await onSave();
setToast({content: 'Product saved'});
} catch {
setToast({content: "Product couldn't be saved", error: true});
}
}
return (
<Frame>
<Button onClick={handleSave}>Save product</Button>
{toast && (
<Toast
content={toast.content}
duration={5000}
error={toast.error}
onDismiss={() => setToast(null)}
/>
)}
</Frame>
);
}Preview
Anchor to Updated propertiesUpdated properties
Map the properties used at each call site to the options passed to shopify.toast.show().
| Polaris React | Toast API | Migration notes |
|---|---|---|
content | First argument to shopify.toast.show() | Pass the message as a string. |
duration | duration | The value remains a duration in milliseconds. |
error | isError | Rename the option. |
action.content | action | Pass the action label as a string. |
action.onAction | onAction | Move the callback to the toast options. |
onDismiss | onDismiss | The Toast API callback runs when the user clicks the dismiss control. Don't use it to detect expiry after duration. |
For example, migrate an undo action from a Polaris React action descriptor:
Migrating a toast action
Polaris web components
shopify.toast.show('Product archived', {
action: 'Undo',
onAction: restoreProduct,
onDismiss: dismissToast,
});Polaris React
<Toast
content="Product archived"
action={{
content: 'Undo',
onAction: restoreProduct,
}}
onDismiss={dismissToast}
/>Anchor to Removed state and hostingRemoved state and hosting
Anchor to Render stateRender state
Remove state used only to mount and unmount Toast, such as active or a nullable toast descriptor. Call shopify.toast.show() from the success or failure path instead.
Keep state that belongs to the underlying operation. For example, a Save button might still need loading state while the request is in progress.
Anchor to FrameFrame
Toast required a Polaris React Frame ancestor. The Toast API renders the notification in the Shopify admin, so it doesn't need an in-iframe host. Remove Frame only after migrating its other consumers, including navigation, loading indicators, and contextual save bars.
Anchor to Explicit dismissalExplicit dismissal
To hide a toast before its duration elapses, store the ID returned by shopify.toast.show() and pass it to shopify.toast.hide(id). Most confirmation toasts should expire on their own.
Anchor to Preserve actionable errorsPreserve actionable errors
A toast is temporary. When an error requires the user to change a field, retry an operation, or refer to details, keep that error visible in the relevant form or page. You can also show an error toast as immediate feedback, but it shouldn't be the only place the recovery instructions appear.
Anchor to Test the migrationTest the migration
- Verify the success, error, action, and manual-dismiss paths used by the app.
- Confirm that repeated actions don't leave stale toast state in the React tree.
- Confirm that route changes and component unmounts don't suppress operation results that should still be shown.
- Test inside the Shopify admin, where the host renders the toast.
Anchor to Remove Polaris ReactRemove Polaris React
After every Toast call site is migrated, remove the Toast import and state used only to render it. Remove Frame separately after its remaining consumers are migrated. Remove @shopify/polaris only after no other route in scope imports it.