Maronato/vue-toastification

Gustavo Maronato

Frontend Engineer
Software Engineer
Vue.js
Light, easy and beautiful toasts!
Wanna try it out? Check out the live demo!
Attention! These are the docs for Vue Toastification v2, which is only compatible with Vue 3+
If you are using Vue 2, check out Vue Toastification v1
Vue 3 compatible!
Generic registration allows it to be used inside any app, even React!
Fully written in Typescript with full types support
RTL support
Easy to set up for real, you can make it work in less than 10sec!
Customize everything
Swipe to close 👌
Use your custom components or JSX as the toast body for endless possibilities!
Create custom experiences with onClose, onClick, and onMounted hooks
Custom toast filtering and enqueueing with lifecycle hooks
Remove toasts programmatically
Update toasts programmatically
Define behavior per toast
Pause toast when hovering and when the window loses focus 👁
Fancy progress bar to display the remaining time
Use your themes and animations easily
And much more!
Need some more convincing? Check out the demo

Add it as a plugin to your app:
import { createApp } from "vue"; import Toast from "vue-toastification"; // Import the CSS or use your own! import "vue-toastification/dist/index.css"; const app = createApp(...); const options = { // You can set your default options here }; app.use(Toast, options);
Or, if you are using Typescript:
import { createApp } from "vue"; import Toast, { PluginOptions } from "vue-toastification"; // Import the CSS or use your own! import "vue-toastification/dist/index.css"; const app = createApp(...); const options: PluginOptions = { // You can set your default options here }; app.use(Toast, options);
To create toasts, get a toast interface by calling useToast from within a component.
<script> import { useToast } from "vue-toastification"; export default { setup() { // Get toast interface const toast = useToast(); // Use it! toast("I'm a toast!"); // or with options toast.success("My toast content", { timeout: 2000 }); // These options will override the options defined in the "app.use" plugin registration for this specific toast // Make it available inside methods return { toast } }, methods: { myMethod() { // Since you returned `toast` from setup(), you can access it now this.toast.info("I'm an info toast!"); } } } </script>
By default, Vue Toastification creates the plugin using a global event bus, so all you need to do to use it outside your components is to call useToast().
// store.js import { createStore } from 'vuex' import { useToast } from 'vue-toastification' const toast = useToast() const store = createStore({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { increment (context) { context.commit('increment') toast.success("incremented!") } } })
By default, the toasts will be displayed at the top right corner of your screen, but you can set it manually using the position option.
You can use the type definitions or one of the allowed values: top-right, top-center, top-left, bottom-right, bottom-center, bottom-left.
import Toast, { POSITION } from "vue-toastification"; app.use(Toast, { // Setting the global default position position: POSITION.TOP_LEFT }); // Or set it per toast toast("I'm a toast", { position: POSITION.BOTTOM_LEFT });
Depending on the context, you may want to use toasts of different colors. You can easily do that by setting the type of toast to be displayed.
toast("Default toast"); toast.info("Info toast"); toast.success("Success toast"); toast.error("Error toast"); toast.warning("Warning toast"); // You can also set the type programmatically when calling the default toast import { TYPE } from "vue-toastification"; toast("Also a success toast", { type: TYPE.SUCCESS // or "success", "error", "default", "info" and "warning" });
Setting the type only works when using toast, it won't work when registering the plugin with app.use.
You can set for how long the toast will remain on the screen (in milliseconds) using the timeout option or disable it altogether by setting it to false
// 1 second toast("Quick toast", { timeout: 1000 }); // Or make the toast permanent until manually closed toast("Persistent toast", { timeout: false }) // Or set it when registering the plugin app.use(Toast, { timeout: 2000 });
Passing strings as the toast content is not enough? You can render anything inside the toast using custom components! Vue Toastification accepts both Vue Components and JSX templates as parameters.
When using custom components, the prop toastId containing the toast ID is always passed by default. Also, an event listener for close-toast is attached, so you can close the toast programmatically by emitting it from inside the component.
See an example with custom components in action:
To use a Single File Component as content just pass it to the toast:
import MyComponent from "./MyComponent.vue"; toast(MyComponent);
When using custom components it is also possible to close the toast from within.
To do that, just emit the close-toast event
// MyComponent.vue <template> <button @click="$emit('close-toast')">Close Toast</button> </template> // OtherFile.vue import MyComponent from "./MyComponent.vue"; // This toast will be closed when the button inside it is clicked toast(MyComponent);
Sometimes you won't want to create a whole component just for a toast. In those cases, you can pass a JSX template to the Toast for it to render as a component

const myJSX = ( <div> <h1>My Title</h1> <span>My text</span> </div> ); // Vue Toastification will generate the appropriate render function automatically. toast(myJSX);
Usually, it is not enough to just render a simple component and you'll need to handle events or pass props. You can do that too!
Just pass the content in the format
{ component: Component, props: { propName: propValue // Optional }, listeners: { eventName: eventHandler // Optional } }
Props will be passed to the created component and the event listeners will be attached to it as well.

const content = { // Your component or JSX template component: MyComponent, // Props are just regular props, but these won't be reactive props: { myProp: "abc", otherProp: 123 }, // Listeners will listen to and execute on event emission listeners: { click: () => console.log("Clicked!"), myEvent: myEventHandler } }; toast(content);
When building custom toast components, it may be useful to access the context of your main app to use stuff that is shared globally inside it. These include things like:
global components such as RouterLink, NuxtLink, etc
global state and properties
custom directives
custom mixins
data from other plugins
To give Vue Toastification access to your app's context, you can set shareAppContext to true during registration.
app.use(Toast, { shareAppContext: true, });
When a toast is created, an ID is assigned to it. You can use it later to programmatically dismiss the toast.
You can also choose a custom ID (String or Number) for the toast during its creation.
// Get the toast ID on creation const toastId = toast("my toast"); // Dismiss it later toast.dismiss(toastId); // Pass your custom ID to the toast toast("my other toast", { id: "my id" }); toast.dismiss("my id");
You can update toasts contents and props programmatically using its ID.
The method signature is $toast.update(id, { content, options }, create) with content, options and create being optional. Updates override previous values.
create is a boolean, false by default. If true, a toast will be created if no matching toast with the id is found.
// Get the toast ID on creation const toastId = toast("Loading..."); // Update it later toast.update(toastId, { content: "Loaded!" }); // Pass your custom ID to the toast toast("my other toast", { id: "my id", timeout: false }); toast.update("my id", { content: "Finished!", options: { timeout: 5000 } });

You can also dismiss all toasts at once using clear.
toast("my toast A"); toast("my toast B"); toast("my toast C"); // Dismiss all toasts toast.clear();
There are two ways to style your toast components. You can either add custom classes to the toast or containers and modify them using those or you can override the actual toast's SCSS when importing them.
toast("my toast", { // For the actual toast, including different toast types: toastClassName: "my-custom-toast-class", // For the toast body when using strings or a custom component as content bodyClassName: ["custom-class-1", "custom-class-2"] });<style> /* When setting CSS, remember that priority increases with specificity, so don't forget to select the existing classes as well */ .Vue-Toastification__toast--default.my-custom-toast-class { background-color: red; } /* Applied to the toast body when using regular strings as content */ .Vue-Toastification__toast-body.custom-class-1 { font-size: 30px; } /* Applied to a wrapper div when using a custom component as content */ .Vue-Toastification__toast-component-body.custom-class-2 { width: 100%; } </style>
These can also be defined when registering the vue plugin.

You can also add custom classes to the toast's containers. Keep in mind that here containers refer to the 6 divs that contain the toasts in the 6 possible toast positions (top-right, top-left, etc).
These classes can be defined during plugin initialization.
app.use(Toast, { // Can be either a string or an array of strings containerClassName: "my-container-class", });<style> /* When setting CSS, remember that priority increases with specificity, so don't forget to select the existing classes as well */ /* This will only affect the top-right container */ .Vue-Toastification__container.top-right.my-container-class{ top: 10em; } /* This will affect all 6 containers */ .Vue-Toastification__container.my-container-class{ position: relative; } </style>
There is a set of pre defined variables that you can override to change some basic styling.
If you have an SCSS loader in your project, simply create a file overriding the defaults
// yourMainScssFile.scss // Override the variables or import a file that overrides them $vt-color-success: white; $vt-text-color-success: #000; // Import the regular Vue Toastification stylesheets (or create your own) @import "vue-toastification/src/scss/_variables"; @import "vue-toastification/src/scss/_toastContainer"; @import "vue-toastification/src/scss/_toast"; @import "vue-toastification/src/scss/_closeButton"; @import "vue-toastification/src/scss/_progressBar"; @import "vue-toastification/src/scss/_icon"; @import "vue-toastification/src/scss/animations/_bounce";
Then you import it when registering the plugin
import Toast from "vue-toastification"; // The magic is here import "./yourMainScssFile.scss"; app.use(Toast);
Right to left layouts are also supported. It can be enabled per toast or globally through plugin options:
// Set RTL on individual toasts toast.success("!detrevnI", { rtl: true }); // Or globally app.use(Toast, { rtl: true });
Vue Toastification comes with built-in transitions, but you can also customize your own.
Default Usage using the built-in bounce transition:
app.use(Toast, { transition: "Vue-Toastification__bounce", maxToasts: 20, newestOnTop: true });
Some of the currently available built-in transitions are:
Bounce (default): Set the transition property to "Vue-Toastification__bounce"
Fade-In / Out: Set the transition property to "Vue-Toastification__fade"
Slide-In / Out (Blurred): Set the transition property to "Vue-Toastification__slideBlurred" However, new ones may be added so be sure to check the live demo page for the updated list.
When registering the plugin you can use your custom transitions as the toasts' transitions. You can use both named transitions or the transition classes separately.
Vue Toastification uses Vue's built-in transition-group components, so read how they work before creating your own.

We'll use the following transition in our examples:
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } .fade-enter-active { animation-name: fadeIn; animation-duration: 750ms; animation-fill-mode: both; } .fade-leave-active { animation-name: fadeOut; animation-duration: 750ms; animation-fill-mode: both; } .fade-move { transition-timing-function: ease-in-out; transition-property: all; transition-duration: 400ms; }
To setup named transitions just pass the transition name.
Using the transition defined above, we can use it like so:
app.use(Toast, { transition: "fade" });
You can also specify which entering, leaving and moving transitions to use. Please note that if you use custom transition classes you'll need to specify all 3 classes for it to work. You can, however, use Vue Toastification's default "bounce" transition to fill the gaps. Its classes are Vue-Toastification__bounce-enter-active, Vue-Toastification__bounce-leave-active and Vue-Toastification__bounce-move.
Example using a mix of fade and bounce transitions:
app.use(Toast, { transition: { enter: "fade-enter-active", leave: "Vue-Toastification__bounce-leave-active", move: "fade-move" } });
By default, all toasts will come with a little icon to the left representing what the message is about. These are fully customizable as you'll see.
You can entirely disable the icon from the toast by setting icon: false when either registering the plugin or creating toasts. Without the icon, the toast's content will fill its place and appear closer to the edge.
// Disable every toast's icon by default app.use(Toast, { icon: false }); // Disable icons per toast toast('No icon!', { icon: false });
You can also use custom icons with the icon option. To do so, you'll probably need to install these icons in your app with an icon library, such as FontAwesome or Material Icons.
You can also install a Vue icon library with custom components, such as Vue FontAwesome.
Using them varies between icon libraries. You can either override icon classes with icon: "my-icon-class", pass a custom component / JSX, or you can set up more complex icon systems by passing an object. Let's look at the options with some examples:
// Using Font Awesome icons toast('Icons are awesome!', { icon: 'fas fa-rocket' }); // Using Material Icons toast('Material icons!', { icon: { iconClass: 'material-icons', // Optional iconChildren: 'check_circle', // Optional iconTag: 'span' // Optional } });
As you can see, we can either just pass a string or define classes, children, and tags for our icons.
When you just pass a string, for example fas fa-rocket, the rendered component will look like:
<i class="fas fa-rocket"></i>
If your icon library supports that, then you're good to go!
Other libraries require you to define icons with ligatures. To support that, Vue Toastification allows you to construct your icon component through some options: iconClass, iconChildren and iconTag.
Taking the Material Icon example from above, the rendered component would look like:
<span class="material-icons">check_circle</span>
Both examples will have an extra class, Vue-Toastification__icon. You can see what it does here or you can override it with your CSS classes.
You can modify the toast close buttons in 3 ways:
Hide it
Use a custom component instead of the standard one
Add extra classes to it
To hide it, simply set closeButton to false when calling the toast or setting up the plugin
toast('No close button', { closeButton: false });
You can also hide the close button unless the toast is being hovered. To do so, set showCloseButtonOnHover to true when calling the toast or setting up the plugin
toast('No close button', { showCloseButtonOnHover: true });
You can also use custom components as close buttons. It accepts Single File Components, JSX and tag names:
toast('With a custom close component', { closeButton: MyComponent });
The close button can be customized with custom classes. These can be either a single string or an array of strings
toast('With custom classes', { closeButtonClassName: "my-button-class" });
If you want to unify the behavior throughout the application and Don't Repeat Yourself, you could extract the default behavior for each type of toast.
import Toast, { TYPE } from "vue-toastification"; const options = { toastDefaults: { // ToastOptions object for each type of toast [TYPE.ERROR]: { timeout: 10000, closeButton: false, }, [TYPE.SUCCESS]: { timeout: 3000, hideProgressBar: true, } } }; app.use(Toast, options);
Some options are only available when registering the plugin, like transition, maxToasts and others. If you need to update those options in runtime, there is a method you can call to update the default options:
const update = { transition: "my-transition" }; toast.updateDefaults(update);

You can use updateDefaults to update any of the default API options, but be careful as they are updated globally, so all new toasts will share the new defaults.
Some applications require custom logic to select which toasts to display and how to display them. To solve this issue, Vue Toastification provides you with two callback functions that give you fine control of your toasts. These are filterBeforeCreate and filterToasts.
Called just before toast creation, filterBeforeCreate allows you to edit toast props in runtime or discard toasts entirely.
It takes two parameters:
The new toast's props
A list of existing toasts
It must return the modified toast props, or false to discard the toast.
Example implementation of a preventDuplicates feature, which prevents toasts of the same type from appearing simultaneously:
// App.js // Prevents toasts of the same type from appearing simultaneously, discarding duplicates const filterBeforeCreate = (toast, toasts) => { if (toasts.filter(t => t.type === toast.type).length !== 0) { // Returning false discards the toast return false; } // You can modify the toast if you want return toast; } app.use(Toast, { filterBeforeCreate });
This callback enables you to filter created toasts from being rendered. It differs from filterBeforeCreate by allowing you to enqueue toasts, as opposed to the former, which allows you to discard them.
It takes the list of created toasts and must return a list of toasts to be rendered. Filtered toasts may be rendered later on.
Another example of preventDuplicates feature that enqueues toasts instead of discarding them:
// App.js // Enqueues toasts of the same type, preventing duplicates const filterToasts = (toasts) => { // Keep track of existing types const types = {}; return toasts.reduce((aggToasts, toast) => { // Check if type was not seen before if (!types[toast.type]) { aggToasts.push(toast); types[toast.type] = true; } return aggToasts; }, []); } app.use(Toast, { filterToasts });
By default, all toasts are mounted to a div that is a direct child of document.body, but your application may require that toasts be mounted elsewhere for whatever reason. Vue Toastification allows you to do that by accepting a container plugin option. That option may be either an HTMLElement or a function that returns or resolves into an HTMLElement.
To use an existing node, simply pass it as the argument:
// App.js const myContainer = document.querySelector('#my-container'); app.use(Toast, { container: myContainer });
You may also use a function that returns the node:
// App.js const getContainer = () => document.querySelector('#my-container'); app.use(Toast, { container: getContainer });
Sometimes your node may not exist by the time the plugin is initialized. This may happen if, for example, it is created by Vue. To dynamically mount your component, pass an async function that resolves into a node instead.
The example below uses the Mutation Observer API to test for a node identifiable by the ID toast-container:
// App.js function asyncGetContainer() { return new Promise(resolve => { const observer = new MutationObserver(function(mutations, me) { const myContainer = document.getElementById("toast-container"); if (myContainer) { me.disconnect(); resolve(myContainer); } }); observer.observe(document, { childList: true, subtree: true }); }); } app.use(Toast, { container: asyncGetContainer });
When setting up a container this way, all calls to toast will still be executed successfully and the toasts will be displayed all at once when it is mounted.
Vue Toastification works by creating a separate Vue App whenever you create a fresh instance of it. This means that you can create as many instances of it as you want and then interact with them independently.
To create a new instance, use createToastInterface:
import { createToastInterface } from "vue-toastification"; const myInterface = createToastInterface();
It accepts all of the regular PluginOptions too:
import { createToastInterface } from "vue-toastification"; const myInterface = createToastInterface({ timeout: 1000 });
When called this way, a new Vue App is created and the Vue Toastification container is attached to it. All calls to the interface methods (myInterface.success(), etc), will trigger toasts to appear inside the new container.
If you want to reuse a Vue Toastification instance, you can provide its EventBus to createToastInterface and get an interface to the existing instance, without creating a new one.
import { createToastInterface, EventBus } from "vue-toastification"; // Create a new event bus const myEventBus = new EventBus(); // Generate the first interface, passing your eventBus as a parameter const toast = createToastInterface({ timeout: 1000, eventBus: myEventBus, }); // Later, generate another interface to the same instance const otherToast = createToastInterface(myEventBus);
You can also create interfaces to existing instances using useToast:
import { useToast } from "vue-toastification"; import { myEventBus } from "./otherFile.js"; const toast = useToast(myEventBus);
, the icon is set automatically depending on the toast type and
attribute of the close button. rtl Boolean
Custom icon class to be used. When set to
attribute of the close button. rtl Boolean
Enables Right to Left layout.
⚠️️ Toast options supersede Plugin Registration props ⚠️
Aside from dropping Vue 2 support in favor of Vue 3, not much has changed between v1.x and v2.x.
this.$toast is not available anymore. Use useToast to get a toast interface. The returning object is identical and has the same methods as this.$toast.
Due to some changes on Vue's transition system, transitionDuration has been deprecated. To change the duration of a transition, change or override the transition classes.
This project was heavily inspired by the beautiful React Toastify project and other great Vue libraries.
Copyright (C) 2020 Maronato. Licensed under MIT
Partner With Gustavo
View Services

More Projects by Gustavo