SweetAlert2 with React — Practical Guide to Alerts, Modals & Hooks
SweetAlert2 (a.k.a. SweetAlert 2, swal2) is a powerful, promise-based alert and modal library. Paired with React it becomes a lightweight, highly customizable replacement for native alerts, confirmation dialogs and form modals. This guide gives you the working patterns you actually need: installation, examples (alerts, confirmation dialogs, async/await flows), forms & validation, file upload dialogs, hooks, and best practices — with links to docs and code samples.
If you prefer reading the original docs, see the official SweetAlert2 site and repo: sweetalert2.github.io, GitHub, and the npm page: npm: sweetalert2. Also useful: a practical walkthrough on Dev.to: Advanced Alert Dialogs and Modals with SweetAlert2 in React.
Install & Get Started
Start with the npm package for module-based projects (CRA, Vite, Next.js). The recommended import is the ES module build; that keeps tree-shaking happy and avoids injecting global CSS unintentionally.
npm install sweetalert2
# or
yarn add sweetalert2
In a React component import the library and optionally the default styles. If you use your own design system, you can omit the CSS and style the modal via custom classes.
import Swal from 'sweetalert2'
import 'sweetalert2/dist/sweetalert2.min.css' // optional
For TypeScript, SweetAlert2 ships with types. For SSR frameworks like Next.js, guard imports behind client-only checks or load dynamically to avoid server-side window/document issues.
Basic Alerts, Confirmations and Toasts
Basic usage is trivial: call Swal.fire() with options. The function returns a Promise with a unified result object, which makes integrating with React’s async flows and hooks straightforward.
Swal.fire({
title: 'Delete item?',
text: "This action can't be undone.",
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Delete'
}).then(result => {
if (result.isConfirmed) {
// proceed
}
})
Confirmation dialogs and toast notifications cover most UX cases. Toasts are unobtrusive and useful for non-blocking feedback (success, info, error). Customize position, timer, and icons to match your app voice. Because returning a Promise is built-in, you can await the result in async event handlers — very handy with fetch requests or optimistic UI updates.
Pro tip: use the built-in showLoaderOnConfirm option in combination with preConfirm to show a loader during async operations, so users get immediate, polished feedback without extra state plumbing in your React component.
Forms, Validation & File Uploads in Modals
SweetAlert2 supports custom HTML content inside the modal and input controls (text, textarea, select, file). That lets you build simple confirmation forms without another modal stack. For moderate complexity prefer a React-controlled form rendered by a portal, but for quick inline inputs SweetAlert2 is perfect.
Swal.fire({
title: 'Enter your name',
input: 'text',
inputPlaceholder: 'John Doe',
showCancelButton: true,
preConfirm: (value) => {
if (!value) {
Swal.showValidationMessage('Name is required')
} else {
return value
}
}
})
For file uploads, use input: ‘file’ and handle the selected File object in preConfirm. Keep in mind browser limits and previewing: convert to base64 or pass FormData to your API. Again, use showLoaderOnConfirm while uploading to keep the UI responsive.
Swal.fire({
title: 'Upload avatar',
input: 'file',
inputAttributes: { accept: 'image/*' },
showCancelButton: true,
preConfirm: (file) => {
if (!file) Swal.showValidationMessage('Select a file')
const fd = new FormData()
fd.append('avatar', file)
return fetch('/api/upload', { method: 'POST', body: fd })
.then(res => res.json())
},
showLoaderOnConfirm: true
})
Validation hooks via preConfirm are synchronous or Promise-returning; they integrate neatly with async validation endpoints. For complex validation and multiple inputs, consider rendering a React form in a custom container inside SweetAlert2 (use html:
and mount a React component into it).
React Patterns: Hooks, Portals and Async Flows
In React you have two main patterns: call SweetAlert2 imperatively from event handlers, or wrap it in a custom hook that returns helpers (openAlert, openConfirm) and handles common behaviors (loading state, error handling). Both are valid; hooks help keep UI logic consistent across the app.
import Swal from 'sweetalert2'
export function useConfirm() {
const confirm = (options) =>
Swal.fire({
icon: 'warning',
showCancelButton: true,
...options
}).then(res => res.isConfirmed)
return { confirm }
}
Async/await is your friend. Awaiting Swal.fire keeps code linear and readable. When using with React state updates, be mindful of component unmounting: avoid setState after unmount by guarding side-effects or by using ref flags.
For accessible modals and correct stacking order in complex apps, render SweetAlert2 into a portal that’s inside your app root, or use SweetAlert2’s built-in container option to target a specific DOM node. This avoids z-index clashes and maintains screen-reader focus order.
Advanced Tips & Best Practices
Keep alerts purposeful. Too many modal interruptions frustrate users. Use toasts for passive feedback and confirmation dialogs only where a user decision is required. SweetAlert2 is flexible enough to produce both, but your UX decisions matter more than the library choice.
Accessibility: SweetAlert2 handles ARIA attributes and focus management reasonably well, but test with screen readers. For complex interactive forms, prefer a fully accessible React form inside a modal container you control, and only use SweetAlert2 for simpler inputs or confirmations.
Performance and bundle size: the core package is small, but if you include SweetAlert2 CSS globally or import extra modules, watch bundle size. Import only what you need. For server-side rendering frameworks, import dynamically or guard window usage to avoid SSR issues.
Troubleshooting & Common Pitfalls
Problem: “Swal.fire is undefined” — usually caused by importing wrong build or SSR. Solution: use dynamic import or check typeof window. In Next.js, import inside useEffect or use dynamic(() => import(‘sweetalert2’), { ssr: false }).
Problem: Styles clash or modal is invisible — check z-index and container. Use container option or mount target to ensure SweetAlert2 is inside your app’s stacking context. Also verify that sweetalert2.min.css is loaded if you expect default styles.
Problem: setState after modal resolves but component unmounted — guard with a mounted ref or cancel logic in useEffect. Because Swal.fire returns a Promise, cancelled components still might attempt state updates when the Promise resolves.
Quick Links & Backlinks (useful references)
- Official SweetAlert2 docs — primary reference for API and examples.
- SweetAlert2 on GitHub — source, issues, contributors.
- npm package — installation and versioning.
- React docs — for hooks, portals, SSR patterns.
- Dev.to: Advanced Alert Dialogs and Modals with SweetAlert2 in React — practical tutorial referenced earlier.
FAQ
How do I use SweetAlert2 in React?
Install via npm (npm i sweetalert2), import Swal from ‘sweetalert2’ and call Swal.fire(…) from event handlers or inside a custom hook. For SSR, import dynamically or inside useEffect to avoid server-side window errors.
Can SweetAlert2 handle forms and validation?
Yes. Use input types (text, textarea, select, file) and preConfirm for validation. For complex forms prefer mounting a React form component into the modal’s HTML container for full control and accessibility.
How do I create confirmation dialogs with async actions?
Use showLoaderOnConfirm and return a Promise from preConfirm or await Swal.fire(…) in an async handler. Handle errors by rejecting the Promise or showing a follow-up alert.

