Promise-based alert, confirm, and prompt dialogs for Svelte 5 – with a drop‑in provider component that lets you fully customize their UI using Svelte Snippets while keeping a simple imperative API.
alert/confirm/prompt returning promises.{#snippet ...}) per dialog type or per individual call.Escape resolves (alert: void, confirm: false, prompt: null).pnpm add dialogs.svelte
# or
npm install dialogs.svelte
or, You can copy the component directly into your project:
Open src/lib/dialogs.svelte
(Copying the component makes it easier to customize styles and other aspects.)
Wrap a layout (or page) with the Dialogs component and provide snippets for any dialogs you want to customize. Omit a snippet to use a default minimal version.
<!-- +layout.svelte -->
<script lang="ts">
import Dialogs from 'dialogs.svelte';
let nameInput = $state('');
</script>
<Dialogs>
<!-- Your app -->
<slot />
{#snippet alert(message, ok)}
<div class="alert">
<p>{message}</p>
<button onclick={ok}>OK</button>
</div>
{/snippet}
{#snippet confirm(message, ok, cancel)}
<div class="confirm">
<p>{message}</p>
<button onclick={ok}>OK</button>
<button onclick={cancel}>Cancel</button>
</div>
{/snippet}
{#snippet prompt(message, defaultValue, ok, cancel)}
<div class="prompt">
<p>{message}</p>
<input
bind:value={nameInput}
{@attach defaultValue
? (el) => {
if (defaultValue) {
nameInput = defaultValue;
el.value = defaultValue;
el.setSelectionRange(0, defaultValue.length);
}
}
: undefined}
/>
<button
onclick={() => {
ok(nameInput);
nameInput = '';
}}>OK</button
>
<button onclick={cancel}>Cancel</button>
</div>
{/snippet}
</Dialogs>
<style>
.alert,
.confirm,
.prompt {
background: #fff;
padding: 1rem 2rem 2rem;
border-radius: 1rem;
}
</style>
Use the dialogs from any descendant component:
<script lang="ts">
import { useDialogs } from 'dialogs.svelte';
const { alert, confirm, prompt } = useDialogs();
async function run() {
await alert('Hello');
const ok = await confirm('Are you sure?');
if (!ok) return;
const name = await prompt('Your name?', 'Alice');
console.log({ name });
}
</script>
<button onclick={run}>Do stuff</button>
If you call useDialogs() outside of a provider, it falls back to the native blocking dialogs automatically.
pnpm installpnpm devpnpm check / pnpm testMIT