API
Every export, with a live example and its options.
Press a button to open the dialog and see what it returns. Each section ends with its options.
confirm
Resolves true from the confirm button and false otherwise. tone: 'danger' makes the button red and focuses Cancel.
'use client'
import { confirm } from 'react-confirm-alert'
export const deleteFile = () =>
confirm({
title: 'Delete “Q3 report.pdf”?',
message: 'It moves to the trash for 30 days.',
tone: 'danger',
confirmLabel: 'Delete',
})
A button that waits
When onConfirm returns a Promise, the button shows a spinner and the dialog stays open until it settles.
'use client'
import { confirm } from 'react-confirm-alert'
const save = () => new Promise<void>((r) => setTimeout(r, 1500))
export const publish = () =>
confirm({
title: 'Publish changes?',
confirmLabel: 'Publish',
onConfirm: save,
})
| Option | Type | What it does |
|---|---|---|
confirmLabel | ReactNode | Confirm button text. Default 'Confirm'. |
cancelLabel | ReactNode | Cancel button text. Default 'Cancel'. |
tone | 'default' | 'danger' | 'danger' paints the button red and focuses Cancel. |
onConfirm | (ctx) => void | Promise | Runs on confirm. A Promise keeps the dialog open. ctx.signal aborts if it closes another way. |
confirm('Delete?') takes a title as a string. Every call also takes the shared options.
alert
Resolves when the dialog closes, from the button, Escape or a click outside.
'use client'
import { alert } from 'react-confirm-alert'
export const showSaved = () =>
alert({ title: 'Saved', message: 'Your changes are safe.' })
| Option | Type | What it does |
|---|---|---|
okLabel | ReactNode | Button text. Default 'OK'. |
prompt
Resolves the text, or null on Cancel, Escape and a click outside. Return a message from validate to keep the dialog open.
'use client'
import { prompt } from 'react-confirm-alert'
export const renameFile = () =>
prompt({
title: 'Rename file',
defaultValue: 'Q3 report.pdf',
validate: (name) => (name.trim() ? null : 'Give it a name'),
})
| Option | Type | What it does |
|---|---|---|
label | ReactNode | Label above the input. |
defaultValue | string | Text the input starts with. |
validate | (value) => string | null | A message keeps the dialog open and shows under the input. Can be async. |
inputProps | input attributes | Such as type, placeholder or maxLength. |
submitLabel | ReactNode | Submit button text. Default 'OK'. |
cancelLabel | ReactNode | Cancel button text. Default 'Cancel'. |
openDialog
Renders your component in a dialog. result resolves what you pass to close(), or undefined on Escape and outside clicks.
'use client'
import { DialogLayout, openDialog } from 'react-confirm-alert'
const plans = ['Free', 'Pro', 'Team']
export const pickPlan = () =>
openDialog<string>({
render: ({ close }) => (
<DialogLayout
title="Pick a plan"
message="You can change it at any time."
actions={plans.map((plan) => ({
label: plan,
onClick: () => close(plan),
}))}
/>
),
}).result
| Option | Type | What it does |
|---|---|---|
render | (props) => ReactNode | Your content. props.close(value) resolves it, props.dismiss() resolves undefined. |
buttons | DialogButton[] | Passed to render, for a layout of your own. |
openDialog() returns a handle:
| Field | Type | What it does |
|---|---|---|
result | Promise<R | undefined> | Resolves when the dialog closes. |
close | (value: R) => void | Closes with a value. |
dismiss | () => void | Closes with undefined. |
update | (patch) => void | Changes options of the open dialog. |
id | DialogId | For closeDialog(id). |
closeDialog and closeAll
closeAll() dismisses every dialog, queued ones too. A confirm resolves false.
'use client'
import { closeAll, confirm } from 'react-confirm-alert'
export function askThenClose() {
setTimeout(closeAll, 2000)
return confirm('This closes in 2 seconds')
}
| Function | What it does |
|---|---|
closeAll() | Dismisses every open and queued dialog. |
closeDialog(id) | Dismisses one dialog, by the id of its handle. |
Dialog
Renders in place and opens while open is true, so its content reads your component's state. Plain HTML inside gets the default look.
'use client'
import { useState } from 'react'
import { Dialog, DialogLayout } from 'react-confirm-alert'
export function EditNote() {
const [open, setOpen] = useState(false)
const [note, setNote] = useState('')
return (
<>
<button onClick={() => setOpen(true)}>Edit note</button>
<output>{note}</output>
<Dialog open={open} onOpenChange={setOpen}>
<DialogLayout
title="Edit note"
message={`${note.length} characters`}
actions={[{ label: 'Done', onClick: () => setOpen(false) }]}
>
<textarea
aria-label="Note"
value={note}
onChange={(e) => setNote(e.target.value)}
/>
</DialogLayout>
</Dialog>
</>
)
}
| Prop | Type | What it does |
|---|---|---|
open | boolean | Shows the dialog. |
onOpenChange | (open) => void | Called with false on Escape and outside clicks. |
children | ReactNode | Your content. DialogLayout lays it out. |
aria-label | string | Names the dialog when there is no DialogLayout title. |
aria-labelledby | string | The id of your own title. |
It also takes modal, closeOnEscape, closeOnClickOutside, onKeyDown, unstyled and classNames from the shared options.
ConfirmDialog
confirm, alert or prompt, rendered in place. Pick one with kind.
'use client'
import { useState } from 'react'
import { ConfirmDialog } from 'react-confirm-alert'
export function LeavePage() {
const [open, setOpen] = useState(false)
const [left, setLeft] = useState(false)
return (
<>
<button onClick={() => setOpen(true)}>Leave page</button>
<output>{left && 'onConfirm ran'}</output>
<ConfirmDialog
kind="confirm"
open={open}
onOpenChange={setOpen}
title="Leave without saving?"
confirmLabel="Leave"
onConfirm={() => setLeft(true)}
/>
</>
)
}
| Prop | Type | What it does |
|---|---|---|
kind | 'confirm' | 'alert' | 'prompt' | Which dialog it is. |
open | boolean | Shows the dialog. |
onOpenChange | (open) => void | Called with false when any button or key closes it. |
onSubmit | (value) => void | Promise | Prompt only. The text, on submit. |
Every option of that kind works as a prop, such as onConfirm, tone or validate.
DialogLayout
Lays out a title, a message, your content and a row of buttons. An action whose onClick returns a Promise is busy until it settles. Use it in openDialog, <Dialog> and customUI.
'use client'
import { DialogLayout, openDialog } from 'react-confirm-alert'
const save = () => new Promise((r) => setTimeout(r, 1500))
export const renameWorkspace = () =>
openDialog({
render: ({ close, dismiss }) => (
<DialogLayout
title="Rename workspace"
message="Everyone in it sees the new name."
actions={[
{ label: 'Cancel', onClick: dismiss },
{
label: 'Save',
variant: 'primary',
onClick: () => save().then(() => close()),
},
]}
>
<input aria-label="Name" defaultValue="Acme" />
</DialogLayout>
),
}).result
| Prop | Type | What it does |
|---|---|---|
title | ReactNode | Heading. It names the dialog when there is no aria-label. |
message | ReactNode | Text under the title. |
actions | DialogAction[] | The buttons, left to right. |
children | ReactNode | Your content, between the message and the buttons. |
Each action takes:
| Field | Type | What it does |
|---|---|---|
label | ReactNode | Button text. |
variant | 'primary' | 'secondary' | 'danger' | Button colour. Default 'secondary'. |
onClick | (event) => void | Promise | A Promise makes the button busy until it settles. |
Any other button attribute, such as type="submit" or disabled, goes on the button.
DialogHost and useDialog
Dialogs render where you place <DialogHost />, so they read the context above it. This site places one inside its theme provider, so the dialog below reads the theme. Switch the theme and open it again.
'use client'
import { useTheme } from 'next-themes'
import { alert } from 'react-confirm-alert'
export function ThemeName() {
const theme = useTheme().resolvedTheme ?? 'light'
return <p>This site is in {theme} mode.</p>
}
export function ShowTheme() {
return (
<button onClick={() => alert({ title: 'Theme', content: <ThemeName /> })}>
Show theme
</button>
)
}
<ThemeProvider>
{children}
<DialogHost dismissKey={usePathname()} />
</ThemeProvider>| Prop | Type | What it does |
|---|---|---|
dismissKey | unknown | When it changes, every dialog closes. Pass the pathname. |
Place one host. Without one, dialogs render in a root of their own and miss your context. The Next.js recipe shows where. useDialog() returns confirm, alert, prompt, openDialog and closeAll, for code that prefers a hook.
configureDialogs
Sets defaults for every dialog. Call it once, where your app starts.
'use client'
import { configureDialogs, confirm } from 'react-confirm-alert'
// Call once, where your app starts.
export const setThaiLabels = () =>
configureDialogs({ labels: { confirm: 'ลบ', cancel: 'ยกเลิก' } })
export const deleteInThai = () =>
confirm({ title: 'ลบไฟล์นี้ไหม', tone: 'danger' })
| Option | Type | What it does |
|---|---|---|
labels | { ok, confirm, cancel, submit } | Default button text. |
modal | boolean | Native modal <dialog>. Default true. |
strategy | 'stack' | 'queue' | 'replace' | What a new dialog does when one is open. Default 'stack'. |
closeOnEscape | boolean | Default true. |
closeOnClickOutside | boolean | Default true. |
lockScroll | boolean | Stops the page from scrolling behind a dialog. Default true. |
unstyled | boolean | Drops the default CSS classes. |
classNames | DialogClassNames | A class per slot. See Styling. |
confirmAlert | object | Separate skin, modal, strategy, unstyled and classNames for confirmAlert. |
Options every dialog takes
confirm, alert, prompt and openDialog take these.
| Option | Type | What it does |
|---|---|---|
title | ReactNode | Heading. |
message | ReactNode | Text under the title. A string keeps its line breaks. |
content | ReactNode | Your JSX between the message and the buttons. |
closeOnEscape | boolean | Default true. |
closeOnClickOutside | boolean | Default true. |
strategy | 'stack' | 'queue' | 'replace' | stack opens on top, the default. queue waits its turn. replace closes the open one. |
modal | boolean | false renders a plain overlay instead of a top-layer <dialog>. |
signal | AbortSignal | Aborting it dismisses the dialog. |
onKeyDown | (event, close) => void | Your own keys. close() dismisses. |
afterClose | () => void | Runs once the dialog has closed. |
unstyled | boolean | Drops the default CSS classes. |
classNames | DialogClassNames | A class per slot. See Styling. |
confirmAlert
The 3.0 API, with its 3.0 look and timing. It returns nothing; each button runs its own onClick.
'use client'
import { confirmAlert } from 'react-confirm-alert'
export function SubmitOrder() {
return (
<button
onClick={() =>
confirmAlert({
title: 'Confirm to submit',
message: 'Are you sure to do this?',
buttons: [{ label: 'Yes' }, { label: 'No' }],
})
}
>
Submit
</button>
)
}
customUI
customUI replaces the whole dialog with your content. skin: true puts it in the new dialog body, where plain HTML gets the default look. Custom UI has more.
'use client'
import { confirmAlert } from 'react-confirm-alert'
export function ShowTerms() {
return (
<button
onClick={() =>
confirmAlert({
skin: true,
customUI: ({ onClose }) => (
<>
<h1>Terms updated</h1>
<p>Read what changed before you go on.</p>
<button data-variant="primary" onClick={onClose}>
Got it
</button>
</>
),
})
}
>
Show terms
</button>
)
}
| Option | Type | What it does |
|---|---|---|
title | string | Heading. |
message | string | Text under the title. |
buttons | object[] | Each has label, onClick and className. Every button closes the dialog. Default Cancel and Confirm. |
customUI | (props) => ReactNode | Replaces the dialog content. props.onClose() closes it. |
skin | boolean | The new look, with customUI too. Default false. |
childrenElement | () => ReactNode | Renders under the message. |
closeOnEscape | boolean | Default true. |
closeOnClickOutside | boolean | Default true. |
onClickOutside | () => void | Runs on a click outside. |
onKeypressEscape | (event) => void | Runs on Escape. |
onkeyPress | (event, close) => void | Runs on any key. |
willUnmount | () => void | Runs before the dialog unmounts. |
afterClose | () => void | Runs after it closes. |
overlayClassName | string | A class on the overlay. |
targetId | string | Renders into the element with this id. |
modal | boolean | Native modal <dialog>. Default false. |
strategy | 'replace' | 'stack' | 'queue' | Default 'replace': a new dialog closes the open one. |
unstyled | boolean | Drops the 3.0 classes. |
classNames | DialogClassNames | A class per slot. |