---
category: Component
outline: deep
---
# createTemplatePromise
Template as Promise. Useful for constructing custom Dialogs, Modals, Toasts, etc.
## Usage
```vue
```
## Features
- **Programmatic** - call your UI as a promise
- **Template** - use Vue template to render, not a new DSL
- **TypeScript** - full type safety via generic type
- **Renderless** - you take full control of the UI
- **Transition** - use support Vue transition
This function is migrated from [vue-template-promise](https://github.com/antfu/vue-template-promise)
## Usage
`createTemplatePromise` returns a **Vue Component** that you can directly use in your template with `
```
Learn more about [Vue Transition](https://vuejs.org/guide/built-ins/transition.html).
## Motivation
The common approach to call a dialog or a modal programmatically would be like this:
```ts
const dialog = useDialog()
const result = await dialog.open({
title: 'Hello',
content: 'World',
})
```
This would work by sending these information to the top-level component and let it render the dialog. However, it limits the flexibility you could express in the UI. For example, you could want the title to be red, or have extra buttons, etc. You would end up with a lot of options like:
```ts
const result = await dialog.open({
title: 'Hello',
titleClass: 'text-red',
content: 'World',
contentClass: 'text-blue text-sm',
buttons: [
{ text: 'OK', class: 'bg-red', onClick: () => {} },
{ text: 'Cancel', class: 'bg-blue', onClick: () => {} },
],
// ...
})
```
Even this is not flexible enough. If you want more, you might end up with manual render function.
```ts
const result = await dialog.open({
title: 'Hello',
contentSlot: () => h(MyComponent, { content }),
})
```
This is like reinventing a new DSL in the script to express the UI template.
So this function allows **expressing the UI in templates instead of scripts**, where it is supposed to be, while still being able to be manipulated programmatically.
## Type Declarations
```ts
export interface TemplatePromiseProps {
/**
* The promise instance.
*/
promise: Promise | undefined
/**
* Resolve the promise.
*/
resolve: (v: Return | Promise) => void
/**
* Reject the promise.
*/
reject: (v: any) => void
/**
* Arguments passed to TemplatePromise.start()
*/
args: Args
/**
* Indicates if the promise is resolving.
* When passing another promise to `resolve`, this will be set to `true` until the promise is resolved.
*/
isResolving: boolean
/**
* Options passed to createTemplatePromise()
*/
options: TemplatePromiseOptions
/**
* Unique key for list rendering.
*/
key: number
}
export interface TemplatePromiseOptions {
/**
* Determines if the promise can be called only once at a time.
*
* @default false
*/
singleton?: boolean
/**
* Transition props for the promise.
*/
transition?: TransitionGroupProps
}
export type TemplatePromise<
Return,
Args extends any[] = [],
> = DefineComponent