---
title: "Alert Dialog"
description: "A modal dialog that interrupts the user with important content and expects a response."
canonical_url: "https://vinicunca.dev/akar/components/alert-dialog"
---
# Alert Dialog

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

```vue [index.vue]
<script setup lang="ts">
import {
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogRoot,
  AlertDialogTitle,
  AlertDialogTrigger,
} from 'akar'
import './styles.css'

function handleAction() {
  // eslint-disable-next-line no-alert
  alert('clicked action button!')
}
</script>

<template>
  <div class="akar-demo akar-demo-AlertDialog">
    <AlertDialogRoot>
        <AlertDialogTrigger class="Button green">
          Delete account
        </AlertDialogTrigger>
        <AlertDialogPortal>
          <AlertDialogOverlay class="AlertDialogOverlay" />
          <AlertDialogContent class="AlertDialogContent">
            <AlertDialogTitle class="AlertDialogTitle">
              Are you absolutely sure?
            </AlertDialogTitle>
            <AlertDialogDescription class="AlertDialogDescription">
              This action cannot be undone. This will permanently delete your account and remove your data from our servers.
            </AlertDialogDescription>
            <div :style="{ display: 'flex', gap: 25, justifyContent: 'flex-end' }">
              <AlertDialogCancel class="Button mauve">
                Cancel
              </AlertDialogCancel>
              <AlertDialogAction
                class="Button red"
                @click="handleAction"
              >
                Yes, delete account
              </AlertDialogAction>
            </div>
          </AlertDialogContent>
        </AlertDialogPortal>
      </AlertDialogRoot>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/mauve.css';
@import '../_colors/red.css';
@import '../_colors/green.css';

@scope (.akar-demo-AlertDialog) {
/* reset */
button {
  all: unset;
}

.AlertDialogOverlay {
  background-color: var(--black-a9);
  position: fixed;
  inset: 0;
  animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
}

.AlertDialogContent {
  background-color: white;
  border-radius: 6px;
  box-shadow: hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 90vw;
  max-width: 500px;
  max-height: 85vh;
  padding: 25px;
  animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
}
.AlertDialogContent:focus {
  outline: none;
}

.AlertDialogTitle {
  margin: 0;
  color: var(--mauve-12);
  font-size: 17px;
  font-weight: 500;
}

.AlertDialogDescription {
  margin-bottom: 20px;
  color: var(--mauve-11);
  font-size: 15px;
  line-height: 1.5;
}

.Button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  padding: 0 15px;
  font-size: 15px;
  line-height: 1;
  font-weight: 500;
  height: 35px;
}
.Button.green {
  background-color: white;
  color: var(--green-11);
  box-shadow: 0 2px 10px var(--black-a7);
}
.Button.green:hover {
  background-color: var(--mauve-3);
}
.Button.green:focus {
  box-shadow: 0 0 0 2px black;
}
.Button.red {
  background-color: var(--red-4);
  color: var(--red-11);
}
.Button.red:hover {
  background-color: var(--red-5);
}
.Button.red:focus {
  box-shadow: 0 0 0 2px var(--red-7);
}
.Button.mauve {
  background-color: var(--mauve-4);
  color: var(--mauve-11);
}
.Button.mauve:hover {
  background-color: var(--mauve-5);
}
.Button.mauve:focus {
  box-shadow: 0 0 0 2px var(--mauve-7);
}

@keyframes overlayShow {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes contentShow {
  from {
    opacity: 0;
    transform: translate(-50%, -48%) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}
}
```

## Features

- Focus is automatically trapped.
- Can be controlled or uncontrolled.
- Manages screen reader announcements with `Title` and `Description` components.
- Esc closes the component automatically.

## Installation

Install the component from your command line.

```bash [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import all parts and piece them together.

```vue
<script setup lang="ts">
import {
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogRoot,
  AlertDialogTitle,
  AlertDialogTrigger,
} from 'akar';
</script>

<template>
  <AlertDialogRoot>
    <AlertDialogTrigger />
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogContent>
        <AlertDialogTitle />
        <AlertDialogDescription />
        <AlertDialogCancel />
        <AlertDialogAction />
      </AlertDialogContent>
    </AlertDialogPortal>
  </AlertDialogRoot>
</template>
```

## API Reference

### Root

Contains all the parts of an alert dialog.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `defaultOpen` |  | `boolean` | The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. |
| `open` |  | `boolean` | The controlled open state of the dialog. Can be binded as `v-model:open`. |
| `unmountOnHide` | `true` | `boolean` | When set to `false`, the dialog content will not be unmounted when closed, but instead hidden with CSS.<br><br>Useful for SEO or when you want to improve performance by not remounting the component on every open. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:open` | `value: boolean` | Event handler called when the open state of the dialog changes. |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `open` | `boolean` | Current open state |
| `close` | `(): void` | Close the dialog |

[AlertDialogRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogRoot.vue)

### Trigger

A button that opens the dialog.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AlertDialogTrigger.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogTrigger.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |

### Portal

When used, portals your overlay and content parts into the `body`.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `defer` |  | `boolean` | Defer the resolving of a Teleport target until other parts of the<br>application have mounted (requires Vue 3.5.0+)<br><br>[reference](https://vuejs.org/guide/built-ins/teleport.html#deferred-teleport) |
| `disabled` |  | `boolean` | Disable teleport and render the component inline<br><br>[reference](https://vuejs.org/guide/built-ins/teleport.html#disabling-teleport) |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |
| `to` |  | `string \| HTMLElement` | Vue native teleport component prop `:to`<br><br>[reference](https://vuejs.org/guide/built-ins/teleport.html#basic-usage) |

[AlertDialogPortal.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogPortal.vue)

### Overlay

A layer that covers the inert portion of the view when the dialog is open.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |

[AlertDialogOverlay.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogOverlay.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |

### Content

Contains content to be rendered when the dialog is open.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `disableOutsidePointerEvents` |  | `boolean` | When `true`, hover/focus/click interactions will be disabled on elements outside<br>the `DismissableLayer`. Users will need to click twice on outside elements to<br>interact with them: once to close the `DismissableLayer`, and again to trigger the element. |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `closeAutoFocus` | `event: Event` | Event handler called when auto-focusing on close.<br>Can be prevented. |
| `escapeKeyDown` | `event: KeyboardEvent` | Event handler called when the escape key is down.<br>Can be prevented. |
| `focusOutside` | `event: FocusOutsideEvent` | Event handler called when the focus moves outside of the `DismissableLayer`.<br>Can be prevented. |
| `interactOutside` | `event: PointerDownOutsideEvent \| FocusOutsideEvent` | Event handler called when an interaction happens outside the `DismissableLayer`.<br>Specifically, when a `pointerdown` event happens outside or focus moves outside of it.<br>Can be prevented. |
| `openAutoFocus` | `event: Event` | Event handler called when auto-focusing on open.<br>Can be prevented. |
| `pointerDownOutside` | `event: PointerDownOutsideEvent` | Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`.<br>Can be prevented. |

[AlertDialogContent.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogContent.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |

### Cancel

A button that closes the dialog. This button should be distinguished visually from `AlertDialogAction` buttons.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AlertDialogCancel.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogCancel.vue)

### Action

A button that closes the dialog. These buttons should be distinguished visually from the `AlertDialogCancel` button.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"button"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AlertDialogAction.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogAction.vue)

### Title

An accessible name to be announced when the dialog is opened. Alternatively, you can provide `aria-label` or `aria-labelledby` to `AlertDialogContent` and exclude this component.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"h2"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AlertDialogTitle.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogTitle.vue)

### Description

An accessible description to be announced when the dialog is opened. Alternatively, you can provide `aria-describedby` to `AlertDialogContent` and exclude this component.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"p"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AlertDialogDescription.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog/AlertDialogDescription.vue)

## Examples

### Close after asynchronous form submission

Use the controlled props to programmatically close the Alert Dialog after an async operation has completed.

```vue
<script setup>
import {
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogOverlay,
  AlertDialogPortal,
  AlertDialogRoot,
  AlertDialogTitle,
  AlertDialogTrigger,
} from 'akar'

const wait = () => new Promise(resolve => setTimeout(resolve, 1000))
const open = ref(false)
</script>

<template>
  <AlertDialogRoot v-model:open="open">
    <AlertDialogTrigger>Open</AlertDialogTrigger>
    <AlertDialogPortal>
      <AlertDialogOverlay />
      <AlertDialogContent>
        <form
          @submit.prevent="
            (event) => {
              wait().then(() => open = false);
            }
          "
        >
          <!-- some inputs -->
          <button type="submit">
            Submit
          </button>
        </form>
      </AlertDialogContent>
    </AlertDialogPortal>
  </AlertDialogRoot>
</template>
```

:br### Custom portal container

Customise the element that your alert dialog portals into.

```vue
<script setup>
import { ref } from 'vue'

const container = ref(null)
</script>

<template>
  <div>
    <AlertDialogRoot>
      <AlertDialogTrigger />
      <AlertDialogPortal :to="container">
        <AlertDialogOverlay />
        <AlertDialogContent>...</AlertDialogContent>
      </AlertDialogPortal>
    </AlertDialogRoot>

    <div ref="container" />
  </div>
</template>
```

## Accessibility

Adheres to the [Alert and Message Dialogs WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog).

### Keyboard Interactions

| Key | Description |
| --- | --- |
| <kbd>Space</kbd> | Opens/closes the dialog. |
| <kbd>Enter</kbd> | Opens/closes the dialog. |
| <kbd>Tab</kbd> | Moves focus to the next focusable element. |
| <kbd>Shift + Tab</kbd> | Moves focus to the previous focusable element. |
| <kbd>Esc</kbd> | Closes the dialog and moves focus to `AlertDialogTrigger`. |

---

- [ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog)
- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/AlertDialog)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
