Github

Alert Dialog

A modal dialog that interrupts the user with important content and expects a response.

"use client";

import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogDemo() {
	return (
		<AlertDialog>
			<AlertDialogTrigger render={<Button variant="tertiary" />}>
				Show Dialog
			</AlertDialogTrigger>
			<AlertDialogContent>
				<AlertDialogHeader>
					<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
					<AlertDialogDescription>
						This action cannot be undone. This will permanently delete your
						account from our servers.
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel>Cancel</AlertDialogCancel>
					<AlertDialogAction>Continue</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

Installation

pnpm dlx shadcn@latest add https://herocn.dev/r/alert-dialog.json

Usage

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
<AlertDialog>
  <AlertDialogTrigger render={<Button variant="outline" />}>
    Show Dialog
  </AlertDialogTrigger>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
      <AlertDialogDescription>
        This action cannot be undone. This will permanently delete your account
        from our servers.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel>Cancel</AlertDialogCancel>
      <AlertDialogAction>Continue</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Composition

Use the following composition to build an AlertDialog:

AlertDialog
├── AlertDialogTrigger
└── AlertDialogContent
    ├── AlertDialogHeader
    │   ├── AlertDialogMedia
    │   ├── AlertDialogTitle
    │   └── AlertDialogDescription
    └── AlertDialogFooter
        ├── AlertDialogCancel
        └── AlertDialogAction

Examples

Basic

A basic alert dialog with a title, description, and cancel and continue buttons.

"use client";

import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogBasic() {
	return (
		<AlertDialog>
			<AlertDialogTrigger
				render={<Button variant="tertiary">Show Dialog</Button>}
			/>
			<AlertDialogContent>
				<AlertDialogHeader>
					<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
					<AlertDialogDescription>
						This action cannot be undone. This will permanently delete your
						account and remove your data from our servers.
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel>Cancel</AlertDialogCancel>
					<AlertDialogAction>Continue</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

Overlay variant

Use overlayVariant on AlertDialogContent to choose an opaque dim (opaque), a blurred backdrop (blur), or transparent overlay (transparent).

"use client";

import {
	AlertDialog,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogOverlayVariant() {
	return (
		<div className="flex flex-wrap gap-2">
			<AlertDialog>
				<AlertDialogTrigger render={<Button variant="tertiary" />}>
					Opaque
				</AlertDialogTrigger>
				<AlertDialogContent overlayVariant="opaque" className="sm:max-w-sm">
					<AlertDialogHeader>
						<AlertDialogTitle>Opaque overlay</AlertDialogTitle>
						<AlertDialogDescription>
							Default dimmed backdrop without extra blur on the page behind the
							AlertDialog.
						</AlertDialogDescription>
					</AlertDialogHeader>
				</AlertDialogContent>
			</AlertDialog>
			<AlertDialog>
				<AlertDialogTrigger render={<Button variant="tertiary" />}>
					Blur
				</AlertDialogTrigger>
				<AlertDialogContent overlayVariant="blur" className="sm:max-w-sm">
					<AlertDialogHeader>
						<AlertDialogTitle>Blurred overlay</AlertDialogTitle>
						<AlertDialogDescription>
							Backdrop blur so content behind the AlertDialog is visibly
							softened.
						</AlertDialogDescription>
					</AlertDialogHeader>
				</AlertDialogContent>
			</AlertDialog>
			<AlertDialog>
				<AlertDialogTrigger render={<Button variant="tertiary" />}>
					Transparent
				</AlertDialogTrigger>
				<AlertDialogContent
					overlayVariant="transparent"
					className="sm:max-w-sm"
				>
					<AlertDialogHeader>
						<AlertDialogTitle>Transparent overlay</AlertDialogTitle>
						<AlertDialogDescription>
							No dimmed backdrop — the page stays fully visible behind the
							AlertDialog surface.
						</AlertDialogDescription>
					</AlertDialogHeader>
				</AlertDialogContent>
			</AlertDialog>
		</div>
	);
}

Small

Use the size="sm" prop to make the alert dialog smaller.

"use client";

import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogSmall() {
	return (
		<AlertDialog>
			<AlertDialogTrigger
				render={<Button variant="tertiary">Show Dialog</Button>}
			/>
			<AlertDialogContent size="sm">
				<AlertDialogHeader>
					<AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
					<AlertDialogDescription>
						Do you want to allow the USB accessory to connect to this device?
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>
					<AlertDialogAction>Allow</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

Media

Use the AlertDialogMedia component to add a media element such as an icon or image to the alert dialog.

"use client";

import { CircleFadingPlusIcon } from "lucide-react";
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogMedia,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogWithMedia() {
	return (
		<AlertDialog>
			<AlertDialogTrigger
				render={<Button variant="tertiary">Share Project</Button>}
			/>
			<AlertDialogContent>
				<AlertDialogHeader>
					<AlertDialogMedia>
						<CircleFadingPlusIcon />
					</AlertDialogMedia>
					<AlertDialogTitle>Share this project?</AlertDialogTitle>
					<AlertDialogDescription>
						Anyone with the link will be able to view and edit this project.
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel>Cancel</AlertDialogCancel>
					<AlertDialogAction>Share</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

Small with Media

Use the size="sm" prop to make the alert dialog smaller and the AlertDialogMedia component to add a media element such as an icon or image to the alert dialog.

"use client";

import { BluetoothIcon } from "lucide-react";
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogMedia,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogSmallWithMedia() {
	return (
		<AlertDialog>
			<AlertDialogTrigger
				render={<Button variant="tertiary">Show Dialog</Button>}
			/>
			<AlertDialogContent size="sm">
				<AlertDialogHeader>
					<AlertDialogMedia>
						<BluetoothIcon />
					</AlertDialogMedia>
					<AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
					<AlertDialogDescription>
						Do you want to allow the USB accessory to connect to this device?
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>
					<AlertDialogAction>Allow</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

Destructive

Use the AlertDialogAction component to add a destructive action button to the alert dialog.

"use client";

import { Trash2Icon } from "lucide-react";
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogMedia,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

export function AlertDialogDestructive() {
	return (
		<AlertDialog>
			<AlertDialogTrigger
				render={<Button variant="destructive">Delete Chat</Button>}
			/>
			<AlertDialogContent size="sm">
				<AlertDialogHeader>
					<AlertDialogMedia className="bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive">
						<Trash2Icon />
					</AlertDialogMedia>
					<AlertDialogTitle>Delete chat?</AlertDialogTitle>
					<AlertDialogDescription>
						This will permanently delete this chat conversation. View{" "}
						<a href="#">Settings</a> to delete any memories saved during this
						chat.
					</AlertDialogDescription>
				</AlertDialogHeader>
				<AlertDialogFooter>
					<AlertDialogCancel variant="tertiary">Cancel</AlertDialogCancel>
					<AlertDialogAction variant="destructive">Delete</AlertDialogAction>
				</AlertDialogFooter>
			</AlertDialogContent>
		</AlertDialog>
	);
}

RTL

To enable RTL support in shadcn/ui, see the RTL configuration guide.

"use client";

import { BluetoothIcon } from "lucide-react";

import {
	type Translations,
	useTranslation,
} from "@/components/language-selector";
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogMedia,
	AlertDialogTitle,
	AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";

const translations: Translations = {
	en: {
		dir: "ltr",
		values: {
			showDialog: "Show Dialog",
			showDialogSm: "Show Dialog (sm)",
			title: "Are you absolutely sure?",
			description:
				"This action cannot be undone. This will permanently delete your account from our servers.",
			cancel: "Cancel",
			continue: "Continue",
			smallTitle: "Allow accessory to connect?",
			smallDescription:
				"Do you want to allow the USB accessory to connect to this device?",
			dontAllow: "Don't allow",
			allow: "Allow",
		},
	},
	ar: {
		dir: "rtl",
		values: {
			showDialog: "إظهار الحوار",
			showDialogSm: "إظهار الحوار (صغير)",
			title: "هل أنت متأكد تمامًا؟",
			description:
				"لا يمكن التراجع عن هذا الإجراء. سيؤدي هذا إلى حذف حسابك نهائيًا من خوادمنا.",
			cancel: "إلغاء",
			continue: "متابعة",
			smallTitle: "السماح للملحق بالاتصال؟",
			smallDescription: "هل تريد السماح لملحق USB بالاتصال بهذا الجهاز؟",
			dontAllow: "عدم السماح",
			allow: "السماح",
		},
	},
	he: {
		dir: "rtl",
		values: {
			showDialog: "הצג דיאלוג",
			showDialogSm: "הצג דיאלוג (קטן)",
			title: "האם אתה בטוח לחלוטין?",
			description:
				"פעולה זו לא ניתנת לביטול. זה ימחק לצמיתות את החשבון שלך מהשרתים שלנו.",
			cancel: "ביטול",
			continue: "המשך",
			smallTitle: "לאפשר להתקן להתחבר?",
			smallDescription: "האם אתה רוצה לאפשר להתקן USB להתחבר למכשיר זה?",
			dontAllow: "אל תאפשר",
			allow: "אפשר",
		},
	},
};

export function AlertDialogRtl() {
	const { dir, language, t } = useTranslation(translations, "ar");

	return (
		<div className="flex gap-4" lang={language} dir={dir}>
			<AlertDialog>
				<AlertDialogTrigger render={<Button variant="tertiary" />}>
					{t.showDialog}
				</AlertDialogTrigger>
				<AlertDialogContent
					dir={dir}
					data-lang={dir === "rtl" ? language : undefined}
				>
					<AlertDialogHeader>
						<AlertDialogTitle>{t.title}</AlertDialogTitle>
						<AlertDialogDescription>{t.description}</AlertDialogDescription>
					</AlertDialogHeader>
					<AlertDialogFooter>
						<AlertDialogCancel>{t.cancel}</AlertDialogCancel>
						<AlertDialogAction>{t.continue}</AlertDialogAction>
					</AlertDialogFooter>
				</AlertDialogContent>
			</AlertDialog>
			<AlertDialog>
				<AlertDialogTrigger render={<Button variant="tertiary" />}>
					{t.showDialogSm}
				</AlertDialogTrigger>
				<AlertDialogContent
					size="sm"
					dir={dir}
					data-lang={dir === "rtl" ? language : undefined}
				>
					<AlertDialogHeader>
						<AlertDialogMedia>
							<BluetoothIcon />
						</AlertDialogMedia>
						<AlertDialogTitle>{t.smallTitle}</AlertDialogTitle>
						<AlertDialogDescription>
							{t.smallDescription}
						</AlertDialogDescription>
					</AlertDialogHeader>
					<AlertDialogFooter>
						<AlertDialogCancel>{t.dontAllow}</AlertDialogCancel>
						<AlertDialogAction>{t.allow}</AlertDialogAction>
					</AlertDialogFooter>
				</AlertDialogContent>
			</AlertDialog>
		</div>
	);
}

API Reference

AlertDialogContent

PropTypeDefault
size"default" | "sm"
"default"

For more information about other components and their props, see the Base UI documentation.