Toast
Push notifications to your visitors with BToast, useToast and BOrchestrator. These are easily customizable for generating alert messages.
Toasts are lightweight notifications designed to mimic the push notifications that have been popularized by mobile and desktop operating systems.
Toasts are intended to be small interruptions to your visitors or users and therefore should contain minimal, to-the-point, non-interactive content. Please refer to the Accessibility Tips section below for important usage information
Overview
This section only refers to using the raw component variation. Toasts are often generated in a global context programmatically, like showing a success message after saving a form. That functionality is covered under the composable docs
The component variation is shown by using the v-model like so
<template>
<div
class="p-3"
style="
min-height: 170px;
background: repeating-linear-gradient(
45deg,
#f8f9fa 0px,
#f8f9fa 10px,
#e9ecef 10px,
#e9ecef 20px
);
"
>
<BButton
class="mb-2"
@click="showToast"
>
Show Toast
</BButton>
<BToast
v-model="show"
variant="info"
solid
>
<template #title> Example toast </template>
This is a toast with a title.
</BToast>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const show = ref(false)
const showToast = () => {
show.value = true
}
</script>By default Toasts are rendered in place. You can use Vue's Teleport to change the location, commonly to body or, more commonly, create toasts using the useToast composable.
Toast features and notes
- Toasts can be generated programmatically via the
useToastcomposable, or manually created using the<BToast>component. - Titles are optional but recommended for accessibility. Titles are rendered inside a
<strong>element unless using thetitleslot. - The close button can be hidden via the
no-close-buttonprop. - A title bar is shown when a title is provided, unless both title and close button are hidden.
- Auto-dismissing is controlled by setting
model-valueto a number of milliseconds. No default auto-hide duration. - When auto-hide is enabled, hovering over the toast pauses the countdown. This can be disabled with the
no-hover-pauseprop. - Toast transparency can be disabled by setting the
solidprop totrue. - Toasts use Vue's
Teleportcomponent for positioning. By default, toasts created withuseToastare teleported to the body. - Toasts include built-in progress bar support via the
progress-propsprop when using timed dismissal. - Toasts support
BLinkintegration for interactive toast bodies.
Positioning
In combination with Teleport, you can render Toasts above the page, and in specific locations. You will need to create a wrapper component around said Toast to declare its location
<template>
<template
v-for="(pos, index) in values"
:key="index"
>
<BButton
class="m-2"
@click="values[index] = !values[index]"
>
{{ locations[index] }}
</BButton>
<Teleport to="body">
<div
:class="locations[index]"
class="toast-container position-fixed p-3"
>
<BToast v-model="values[index]">
<template #title> Title </template>
{{ locations[index] }}
</BToast>
</div>
</Teleport>
</template>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const locations = [
'top-0 start-0',
'top-0 start-50 translate-middle-x',
'top-0 end-0',
'top-50 start-0 translate-middle-y',
'top-50 start-50 translate-middle',
'top-50 end-0 translate-middle-y',
'bottom-0 start-0',
'bottom-0 start-50 translate-middle-x',
'bottom-0 end-0',
]
const values = ref(Array.from({length: locations.length}, () => false))
</script>Static placement
You can place toasts in static placements, and with more control by using them directly. Although, it is more uncommon
<template>
<BToast
v-model="active"
variant="info"
>
<template #title> Title </template>
Body
</BToast>
<BButton @click="active = !active">Toggle</BButton>
</template>
<script setup lang="ts">
import {ref} from 'vue'
const active = ref(false)
</script>Auto-dismissing Toasts
To create a BToast that dismisses automatically after a specified duration, set the model-value prop to the number of milliseconds you want the BToast to remain visible. By default, the timer updates on every browser frame via requestAnimationFrame (roughly every 16 ms). To throttle updates for example to once per second—set the interval prop to 1000 (or any millisecond value). Timed Toasts automatically pause when hovered over with a mouse, but you can disable this behavior using the no-hover-pause prop. Ensure that the model-value is an integer representing milliseconds. Any change to the model-value will reset the timer.
The interval prop determines how frequently the timer updates. While the default is requestAnimationFrame, you can set a custom interval. Negative values for either model-value or interval will stop the timer. If the model-value does not divide evenly by the interval, the timer will continue to the nearest interval. For example, a model-value of 5400 ms with an interval of 1000 ms will run for 6000 ms. To avoid this, choose an interval that divides evenly into the model-value, such as 540 ms or 1080 ms.
<template>
<BButton
@click="
create({
title: 'Counting down!',
variant: 'info',
pos: 'middle-center',
modelValue: 10000,
progressProps: {
variant: 'danger',
},
body: 'Watch me!',
})
"
>
Show
</BButton>
</template>
<script setup lang="ts">
import {useToast} from 'bootstrap-vue-next'
const {create} = useToast()
</script>Toast roles
Toasts are rendered with a default role attribute of 'alert' and aria-live attribute of 'assertive'. For toasts that are meant for a casual notification, set the is-status prop to true, which will change the role and aria-live attributes to 'status' and 'polite' respectively.
For more information, please see the Accessibility section below.
ProgressBar Integration
As you may have noticed in that example, there was a built-in progress bar. This is triggered when using a value that is a number and when progress-props is not undefined. This was implemented because it can be difficult to modify the behavior of BToast when using a pure method, and the appearance of a ticking down progress bar is a "nice-to-have". Although it is not out of the box behavior by Bootstrap, its behavior is opt-in. This functions similarly to examples in BAlert
BLink Integration
Toast can accept BLink props which will modify its behavior
<template>
<BButton
@click="
create({
href: 'https://getbootstrap.com/',
modelValue: true,
target: '_blank',
body: 'I am a BLink',
})
"
>
Show
</BButton>
</template>
<script setup lang="ts">
import {useToast} from 'bootstrap-vue-next'
const {create} = useToast()
</script>Programmatically Control
To programmatically control your toasts with global state, refer to our documentation at useToast
Accessibility
Toasts are intended to be small interruptions to your visitors or users, so to help those with screen readers and similar assistive technologies, toasts are wrapped in an aria-live region. Changes to live regions (such as injecting/updating a toast component) are automatically announced by screen readers without needing to move the user's focus or otherwise interrupt the user. Additionally, aria-atomic="true" is automatically set to ensure that the entire toast is always announced as a single (atomic) unit, rather than announcing what was changed (which could lead to problems if you only update part of the toast's content, or if displaying the same toast content at a later point in time).
If you just need a single simple message to appear along the bottom or top of the user's window, use a fixed position BAlert instead.
Accessibility tips
Typically, toast messages should display one or two-line non-critical messages that do not require user interaction. Without taking extra steps, toasts can have numerous accessibility issues that can impact both people with and without disabilities. The following list, while not complete, provides general guidelines when using toasts.
- If the information needed is important for the process, e.g. for a list of errors in a form, then use the
<BAlert>component instead of<BToast>. <BToast>, by default, sets the attributesroleto'alert'andaria-liveto'assertive'. If it's an important message like an error, this default setting is appropriate, otherwise set the propis-statustotruewhich will change the attributesroleto'status'andaria-liveto'polite'.- Avoid popping up a toast message on page load. Performing unexpected actions on page load is very confusing to screen reader users. If a toast is needed on page load or route change, delay showing the toast by several seconds so that the screen reader will finish announcing information about the current page without interruption by the toast.
- When the toast is persistently visible (i.e., when
model-valueis set totrueand the toast does not auto-dismiss), you must have a close button to allow users to dismiss the toast. If you have also set the propno-close-buttontotrue, you must provide your own close button or dismiss the toast by some other means. Toasts have a tab index of0so that they can be reached by keyboard-only users. Ifmodel-valueis set tofalse, the toast is not visible and no close button is required. - Avoid initiating many toasts in quick succession, as screen readers may interrupt reading the current toast and announce the new toast, causing the context of the previous toast to be missed.
- For toasts with long textual content, set
model-valueto a larger timeout value, to allow users time to read the content of the toast. The average person reads about 200 words per minute, so a good length of time to keep messages up is 5 seconds, plus 300 extra milliseconds per word. The shortest default that should be used as a best practice is 5 seconds (5000ms). In addition to a reasonable default timeout, you could also allow the user to choose how long they want toasts to stay up for. Most people inherently understand whether they are fast or slow readers. Having a profile setting that is part of the user login will allow slow readers to pick a longer time if the messages are going away too fast, and fast readers to pick a short time if the messages are staying up too long. - To account for memory loss and distraction as well as disability-related issues such as ADHD, a best practice would be to implement a location where users can refer to a list of past toast messages which have been shown. Preferably this list should be sortable, with the default being chronological.
Component Reference
<BToast>
| Prop | Type | Default | Description |
|---|---|---|---|
| bg-variant | ColorVariant | null | null | Applies one of the Bootstrap theme color variants to background of the component |
| body | string | undefined | The text content of the body |
| body-class | ClassValue | undefined | CSS class (or classes) to apply to the body |
| close-class | ClassValue | undefined | CSS class (or classes) to apply to the close button |
| close-content | string | undefined | Sets the text for the close button. The `close` slot takes precedence |
| close-label | string | 'Close' | Sets the `aria-label` attribute for the close button |
| close-variant | ButtonVariant | null | null | Sets the color variant for the close button |
| header-class | ClassValue | undefined | CSS class (or classes) to apply to the header |
| header-tag | string | 'div' | Specify the HTML tag to render instead of the default tag for the header |
| id | string | undefined | Used to set the `id` attribute on the rendered content, and used as the base to generate any additional element IDs as needed |
| initial-animation | boolean | false | When set, enables the initial animation on mount |
| interval | number | "requestAnimationFrame" | 'requestAnimationFrame' | Sets the interval for refreshing the countdown timer |
| is-status | boolean | false | When set to `true`, sets `aria-live="polite"` and `role="status"`; otherwise, `aria-live="assertive"` and `role="alert"` |
| lazy | boolean | false | When set, the content will not be mounted until opened |
| model-value | boolean | number | false | Controls toast visibility (`boolean`) or sets the auto-dismiss duration in milliseconds (`number`). |
| no-animation | boolean | false | When set, disables the animation |
| no-close-button | boolean | false | Hides the close button in the toast header. |
| no-fade | boolean | false | Alias for `noAnimation` |
| no-hover-pause | boolean | false | When set to true, disables pausing the timer on hover behavior |
| no-progress | boolean | false | Hides the progress bar in the toast. |
| no-resume-on-hover-leave | boolean | false | When set to true, the timer will not resume when the mouse leaves the element. It will need to be manually resumed |
| progress-props | Omit<BProgressBarProps, 'label' | 'max' | 'value'> | undefined | Configures the progress bar. No progress bar is shown if undefined |
| show | boolean | false | When set, and prop 'visible' is false on mount, will animate from closed to open on initial mount. Mainly to help with template show. Use model-value for reactive show/hide |
| show-on-pause | boolean | true | Keeps the component visible when paused |
| solid | boolean | false | Renders the toast with a solid background instead of a translucent one. |
| text-variant | TextColorVariant | null | null | Applies one of the Bootstrap theme color variants to the text |
| title | string | undefined | Text content to place in the title |
| toast-class | ClassValue | undefined | Sets the CSS class(es) for the toast wrapper element. |
| trans-props | TransitionProps | undefined | Transition properties |
| unmount-lazy | boolean | false | When set and `lazy` is true, the content will be unmounted when closed |
| variant | ColorVariant | null | null | Applies one of the Bootstrap theme color variants to the component. When implemented `bg-variant` and `text-variant` will take precedence |
| visible | boolean | false | When 'true', open without animation |
| Event | Args | Description |
|---|---|---|
| cancel | value: BvTriggerableEvent | Emitted when a cancel action is triggered. |
| close | value: BvTriggerableEvent - The event object for the close button click. | Emitted when the close button is clicked. |
| close-countdown | value: number - The remaining time in milliseconds before auto-dismissal. | Emitted during the countdown to auto-dismiss. |
| hidden | value: BvTriggerableEvent | Always emits after the component is hidden |
| hide | value: BvTriggerableEvent - Call value.preventDefault() to cancel hide | Always emits just before the component has hidden. Cancelable (as long as component wasn't forcibly hidden) |
| hide-prevented | value: BvTriggerableEvent | Emitted when the component tried to close, but was prevented from closing. This occurs when preventDefault() is called on the event, the user clicks escape and no-close-onbackdrop is set to true, or the user clicks on the backdrop and no-close-onbackdrop is set to true. |
| ok | value: BvTriggerableEvent | Emitted when an ok action is triggered. |
| show | value: BvTriggerableEvent - Call value.preventDefault() to cancel show | Always emits just before the component is shown. Cancelable |
| show-prevented | value: BvTriggerableEvent | Emitted when the component tried to open, but was prevented from opening. This occurs when preventDefault() is called on the event |
| shown | value: BvTriggerableEvent | Always emits just after component is shown. |
| toggle | value: BvTriggerableEvent - Call value.preventDefault() to cancel hide | Always emits just before the component is toggled via the exposed 'toggle()' function or useToggle composable . Cancelable (as long as component wasn't forcibly hidden) |
| toggle-prevented | value: BvTriggerableEvent | Emitted when the component tried to toggle, but was prevented from doing so. This occurs when preventDefault() is called on the event, the user clicks escape and no-close-onbackdrop is set to true, or the user clicks on the backdrop and no-close-onbackdrop is set to true. |
| update:model-value | value: boolean | number - The new visibility state (boolean) or countdown duration in milliseconds (number). When boolean: true = visible, false = hidden. When number: > 0 = countdown duration, 0 = countdown finished. | Emitted when the toast visibility or countdown duration changes. |
| Name | Scope | Description |
|---|---|---|
| close | id: string - The toast component IDshow: () => void - Function to show the toasthide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the toasttoggle: () => void - Function to toggle toast visibilityactive: boolean - Whether the countdown timer is activevisible: boolean - Current visibility state of the toast | Content to place in the close button |
| default | id: string - The toast component IDshow: () => void - Function to show the toasthide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the toasttoggle: () => void - Function to toggle toast visibilityactive: boolean - Whether the countdown timer is activevisible: boolean - Current visibility state of the toast | Content to place in the toast body |
| title | id: string - The toast component IDshow: () => void - Function to show the toasthide: (trigger?: string, noTriggerEmit?: boolean) => void - Function to hide the toasttoggle: () => void - Function to toggle toast visibilityactive: boolean - Whether the countdown timer is activevisible: boolean - Current visibility state of the toast | Content to place in the toast header as title |