Skip to content
SevenUI
Esc
navigateopen⌘Jpreview
Sign in
On this page

Alert Dialog

A modal dialog that interrupts the user with important content and expects a response, built on the Base UI Alert Dialog primitive.

"use client";

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

export default function AlertDialogDemo() {
  return (
    <AlertDialog>
      <AlertDialogTrigger
        render={<Button variant="outline">Delete account</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 variant="destructive">
            Delete account
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Installation

npx shadcn@latest add https://sevenui.dev/r/alert-dialog.json

Usage

"use client";

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

export default function AlertDialogDemo() {
  return (
    <AlertDialog>
      <AlertDialogTrigger
        render={<Button variant="outline">Delete account</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>
  );
}

Examples

With media

AlertDialogMedia renders an icon tile; size="sm" produces the compact, center-aligned layout.

"use client";

import { Trash2Icon } from "lucide-react";

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

export default function AlertDialogMediaDemo() {
  return (
    <AlertDialog>
      <AlertDialogTrigger
        render={<Button variant="outline">Delete file</Button>}
      />
      <AlertDialogContent size="sm">
        <AlertDialogHeader>
          <AlertDialogMedia>
            <Trash2Icon />
          </AlertDialogMedia>
          <AlertDialogTitle>Delete this file?</AlertDialogTitle>
          <AlertDialogDescription>
            "quarterly-report.pdf" will be permanently removed.
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction variant="destructive">Delete</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

API reference

AlertDialog

Extends the Base UI Alert Dialog Root. Always modal and never dismissed by an outside press — both are enforced by the primitive itself: the Root accepts no modal or disablePointerDismissal props, unlike the plain Dialog. Escape still closes it; it renders with role="alertdialog".

Prop Type Default
open / defaultOpen boolean false
onOpenChange (open: boolean) => void

AlertDialogContent

Content is centered by an AlertDialog.Viewport — long content scrolls the viewport, not the page.

Prop Type Default
size "default" | "sm" "default"

AlertDialogAction and AlertDialogCancel

Both are Close parts: they close the dialog regardless of which one is pressed, so attach the destructive handler via onClick on AlertDialogAction. Both expose Button’s variant/size — use variant="destructive" on the action for delete flows.

For async confirms that should keep the dialog open until the work finishes, control the dialog and cancel the close:

<AlertDialog
  open={open}
  onOpenChange={(nextOpen, eventDetails) => {
    if (!nextOpen && pending) {
      eventDetails.cancel(); // keep it open while the request runs
      return;
    }
    setOpen(nextOpen);
  }}
>

AlertDialogTrigger, AlertDialogHeader, AlertDialogMedia, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogOverlay, AlertDialogPortal

Styled parts. AlertDialogMedia renders an icon tile above the header (spans both text rows at the default size); the trigger accepts the render prop.

Was this page helpful?