Skip to content

Dialogs

Dialogs ask the user to acknowledge information or make a decision before a plugin continues. Access them through ctx.dialogs after requesting the api.dialog permission.

{
"recall": {
"permissions": ["api.dialog"]
}
}

Use alert() when the user only needs to acknowledge a message:

await ctx.dialogs.alert({
title: "Import complete",
description: "Your learning data is ready to use.",
actionText: "Continue",
});

Use confirm() when the next action depends on an explicit decision. It resolves to true for the primary action and false for cancellation.

const confirmed = await ctx.dialogs.confirm({
title: "Delete this deck?",
description: "Its cards and learning progress will be removed.",
actionText: "Delete deck",
cancelText: "Keep deck",
variant: "destructive",
waitBeforeAction: 2,
});
if (confirmed) {
await ctx.commands.run("deck.delete", { deckId });
}

Both methods accept the following options:

OptionTypeDescription
titlestringShort heading explaining why the dialog is open.
descriptionstringOptional context or consequences shown below the title.
actionTextstringOptional primary-action label. The app supplies a default when omitted.
variant"default" | "warning" | "destructive"Requested visual emphasis.
waitBeforeActionnumberOptional delay in seconds before the primary action is enabled.

confirm() also accepts cancelText, an optional string label for its cancel action.

Use waitBeforeAction sparingly, usually for destructive actions where a short pause reduces accidental confirmation.

Calling alert() or confirm() creates and opens one temporary dialog. There is no registration or lifecycle-event API. Await the result; once the user responds and the dialog closes, the app disposes it.

For brief feedback that requires no response, use a toast instead. Do not use a toast when the plugin must wait for acknowledgement or a decision.