{"id":13624797,"url":"https://github.com/xiaoluoboding/vue-sonner","last_synced_at":"2025-05-13T22:03:58.706Z","repository":{"id":148758692,"uuid":"607054697","full_name":"xiaoluoboding/vue-sonner","owner":"xiaoluoboding","description":"🔔 An opinionated toast component for Vue \u0026 Nuxt.","archived":false,"fork":false,"pushed_at":"2025-02-22T14:20:07.000Z","size":9730,"stargazers_count":1043,"open_issues_count":38,"forks_count":52,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T19:06:08.835Z","etag":null,"topics":["component-library","nuxt3","toast","vue3","vuejs"],"latest_commit_sha":null,"homepage":"https://vue-sonner.robertshaw.id","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xiaoluoboding.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["xiaoluoboding"]}},"created_at":"2023-02-27T08:05:50.000Z","updated_at":"2025-04-10T14:53:35.000Z","dependencies_parsed_at":"2023-05-28T21:15:38.256Z","dependency_job_id":"1c6a1390-e1a1-48bc-b8fc-06ffa2c18270","html_url":"https://github.com/xiaoluoboding/vue-sonner","commit_stats":{"total_commits":176,"total_committers":21,"mean_commits":8.380952380952381,"dds":"0.40909090909090906","last_synced_commit":"a5b77c2df08d5c05aa923170176168102855533d"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaoluoboding%2Fvue-sonner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaoluoboding%2Fvue-sonner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaoluoboding%2Fvue-sonner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xiaoluoboding%2Fvue-sonner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xiaoluoboding","download_url":"https://codeload.github.com/xiaoluoboding/vue-sonner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251341000,"owners_count":21574028,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component-library","nuxt3","toast","vue3","vuejs"],"created_at":"2024-08-01T21:01:46.556Z","updated_at":"2025-04-28T15:43:30.139Z","avatar_url":"https://github.com/xiaoluoboding.png","language":"Vue","readme":"# Sonner for Vue\n\n[![NPM][npmBadge]][npmUrl]\n[![Minzip Package][bundlePhobiaBadge]][bundlePhobiaUrl]\n[![NPM Download][npmDtBadge]][npmDtUrl]\n\n[npmBadge]: https://img.shields.io/npm/v/vue-sonner.svg?maxAge=2592000\n[npmUrl]: https://www.npmjs.com/package/vue-sonner\n[npmDtBadge]: https://img.shields.io/npm/dt/vue-sonner.svg\n[npmDtUrl]: https://www.npmjs.com/package/vue-sonner\n[bundlePhobiaBadge]: https://img.shields.io/bundlephobia/minzip/vue-sonner\n[bundlePhobiaUrl]: https://bundlephobia.com/package/vue-sonner@latest\n\n\u003e An opinionated toast component for Vue. It's a Vue port of Sonner\n\n## Preview\n\nhttps://user-images.githubusercontent.com/6118824/228208185-be5aefd4-7fa8-4f95-a41c-88a60c0e2800.mp4\n\n## Introduction\n\n`Vue Sonner` is an opinionated toast component for Vue. It's customizable, but styled by default. Comes with a swipe to dismiss animation.\n\n## Table of Contents\n\n\u003cdetails\u003e\n\n\u003csummary\u003eTOC\u003c/summary\u003e\n\n- [Sonner for Vue](#sonner-for-vue)\n  - [Preview](#preview)\n  - [Introduction](#introduction)\n  - [Table of Contents](#table-of-contents)\n  - [Installation](#installation)\n  - [Test](#test)\n    - [Launching the test](#launching-the-test)\n    - [Build and watch for change in order to fix the test](#build-and-watch-for-change-in-order-to-fix-the-test)\n  - [Usage](#usage)\n    - [For Vue 3](#for-vue-3)\n    - [For Nuxt 3](#for-nuxt-3)\n    - [CDN Link](#cdn-link)\n  - [Types](#types)\n    - [Default](#default)\n    - [Success](#success)\n    - [Error](#error)\n    - [Action](#action)\n    - [Promise](#promise)\n    - [Custom Component](#custom-component)\n  - [Customization](#customization)\n    - [Headless](#headless)\n    - [Theme](#theme)\n    - [Position](#position)\n    - [Expanded](#expanded)\n    - [Styling for all toasts](#styling-for-all-toasts)\n    - [Styling for individual toast](#styling-for-individual-toast)\n    - [Tailwind CSS](#tailwind-css)\n    - [Changing Icon](#changing-icon)\n    - [Close button](#close-button)\n    - [Rich colors](#rich-colors)\n    - [Custom offset](#custom-offset)\n    - [On Close Callback](#on-close-callback)\n    - [Persisting toasts](#persisting-toasts)\n    - [Dismissing toasts programmatically](#dismissing-toasts-programmatically)\n    - [Keyboard focus](#keyboard-focus)\n  - [Inspiration](#inspiration)\n  - [License](#license)\n\n\u003c/details\u003e\n\n## Installation\n\nTo start using the library, install it in your project:\n\n```bash\npnpm install vue-sonner\nor\nyarn add vue-sonner\n```\n\n## Test\n\nTo run the test you need two separate CLI window :\n\n### Launching the test\n\nTo launch the test, you need to go in the test directory\n\n```bash\ncd ./test\n```\n\nand launch the following command\n\n```bash\ncd ./test\npnpm test:e2e --ui\n```\n\n### Build and watch for change in order to fix the test\n\nThis command will build the vue-sonner library in lib mode, and add a watch so every time you modify the code of the library, you will have a new bundle and can run the test again.\n\n```bash\npnpm build:dev\n```\n\n## Usage\n\n### For Vue 3\n\n```html\n\u003c!-- App.vue --\u003e\n\u003ctemplate\u003e\n  \u003cToaster /\u003e\n  \u003cbutton @click=\"() =\u003e toast('My first toast')\"\u003eRender a toast\u003c/button\u003e\n\u003c/template\u003e\n\n\u003cscript lang=\"ts\" setup\u003e\n  import { Toaster, toast } from 'vue-sonner'\n\u003c/script\u003e\n```\n\n### For Nuxt 3\n\nUse `vue-sonner/nuxt` module\n\n```ts\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  ...\n  modules: ['vue-sonner/nuxt']\n})\n```\n\nUse `Toaster` component and `$toast` function anywhere in the Vue SFC\n\n```html\n\u003c!-- app.vue --\u003e\n\u003ctemplate\u003e\n  \u003cdiv\u003e\n    \u003cToaster position=\"top-right\" /\u003e\n    \u003cbutton @click=\"() =\u003e $toast('My first toast')\"\u003eRender a toast\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript setup lang=\"ts\"\u003e\n  const { $toast } = useNuxtApp()\n\u003c/script\u003e\n```\n\n### CDN Link\n\n**EMS version**\n\n```ts\nhttps://cdn.jsdelivr.net/npm/vue-sonner/+esm\n```\n\n**UMD version**\n\n```ts\nhttps://www.unpkg.com/vue-sonner@0.3.1/lib/vue-sonner.umd.cjs\n```\n\n## Types\n\n### Default\n\nMost basic toast. You can customize it (and any other type) by passing an options object as the second argument.\n\n```ts\ntoast('Event has been created')\n```\n\nWith custom description:\n\n```ts\ntoast('Event has been created', {\n  description: 'Monday, January 3rd at 6:00pm'\n})\n```\n\n### Success\n\nRenders a checkmark icon in front of the message.\n\n```ts\ntoast.success('Event has been created')\n```\n\n### Error\n\nRenders an error icon in front of the message.\n\n```ts\ntoast.error('Event has not been created')\n```\n\n### Action\n\nRenders a button.\n\n```ts\ntoast('Event has been created', {\n  action: {\n    label: 'Undo',\n    onClick: () =\u003e console.log('Undo')\n  }\n})\n```\n\n### Promise\n\nStarts in a loading state and will update automatically after the promise resolves or fails.\n\nYou can pass a function to the success/error messages to incorporate the result/error of the promise.\n\n```ts\ntoast.promise(() =\u003e new Promise((resolve) =\u003e setTimeout(resolve, 2000)), {\n  loading: 'Loading',\n  success: (data: any) =\u003e 'Success',\n  error: (data: any) =\u003e 'Error'\n})\n```\n\n### Custom Component\n\nYou can pass a Vue Component as the first argument instead of a string to render custom Component while maintaining default styling. You can use the headless version below for a custom, unstyled toast.\n\n```html\n\u003cscript lang=\"ts\" setup\u003e\n  import { defineComponent, h, markRaw } from 'vue'\n\n  const CustomDiv = defineComponent({\n    setup() {\n      return () =\u003e\n        h('div', {\n          innerHTML: 'A custom toast with unstyling'\n        })\n    }\n  })\n\n  toast(markRaw(CustomDiv))\n\u003c/script\u003e\n```\n\n## Customization\n\n### Headless\n\nYou can use `toast.custom` to render an unstyled toast with custom jsx while maintaining the functionality.\n\n```vue\n\u003cscript lang=\"ts\" setup\u003e\nimport { markRaw } from 'vue'\n\nimport HeadlessToast from './HeadlessToast.vue'\n\ntoast.custom(markRaw(HeadlessToast), { duration: 999999 })\n\u003c/script\u003e\n```\n\n### Theme\n\nYou can change the theme using the `theme` prop. Default theme is light.\n\n```html\n\u003cToaster theme=\"dark\" /\u003e\n```\n\n### Position\n\nYou can change the position through the `position` prop on the `\u003cToaster /\u003e` component. Default is `top-right`.\n\n```html\n\u003c!-- Available positions --\u003e\n\u003c!-- top-left, top-center, top-right, bottom-left, bottom-center, bottom-right --\u003e\n\n\u003cToaster position=\"top-center\" /\u003e\n```\n\n### Expanded\n\nToasts can also be expanded by default through the `expand` prop. You can also change the amount of visible toasts which is 3 by default.\n\n```html\n\u003cToaster expand :visibleToasts=\"9\" /\u003e\n```\n\n### Styling for all toasts\n\nYou can style your toasts globally with the `toastOptions` prop in the `Toaster` component.\n\n```html\n\u003cToaster\n  :toastOptions=\"{\n    style: { background: 'red' },\n    class: 'my-toast',\n    descriptionClass: 'my-toast-description'\n  }\"\n/\u003e\n```\n\n### Styling for individual toast\n\n```ts\ntoast('Event has been created', {\n  style: {\n    background: 'red'\n  },\n  class: 'my-toast',\n  descriptionClass: 'my-toast-description'\n})\n```\n\n### Tailwind CSS\n\nThe preferred way to style the toasts with tailwind is by using the `unstyled` prop. That will give you an unstyled toast which you can then style with tailwind.\n\n```vue\n\u003cToaster\n  :toastOptions=\"{\n    unstyled: true,\n    classes: {\n      toast: 'bg-blue-400',\n      title: 'text-red-400',\n      description: 'text-red-400',\n      actionButton: 'bg-zinc-400',\n      cancelButton: 'bg-orange-400',\n      closeButton: 'bg-lime-400'\n    }\n  }\"\n/\u003e\n```\n\nYou can do the same when calling `toast()`.\n\n```ts\ntoast('Hello World', {\n  unstyled: true,\n  classes: {\n    toast: 'bg-blue-400',\n    title: 'text-red-400 text-2xl',\n    description: 'text-red-400',\n    actionButton: 'bg-zinc-400',\n    cancelButton: 'bg-orange-400',\n    closeButton: 'bg-lime-400'\n  }\n})\n```\n\nStyling per toast type is also possible.\n\n```vue\n\u003cToaster\n  :toastOptions=\"{\n    unstyled: true,\n    classes: {\n      error: 'bg-red-400',\n      success: 'text-green-400',\n      warning: 'text-yellow-400',\n      info: 'bg-blue-400'\n    }\n  }\"\n/\u003e\n```\n\n### Changing Icon\n\nYou can change the default icons using slots:\n\n```vue\n\u003cToaster\u003e\n  \u003ctemplate #loading-icon\u003e\n    \u003cLoadingIcon /\u003e\n  \u003c/template\u003e\n  \u003ctemplate #success-icon\u003e\n    \u003cSuccessIcon /\u003e\n  \u003c/template\u003e\n  \u003ctemplate #error-icon\u003e\n    \u003cErrorIcon /\u003e\n  \u003c/template\u003e\n  \u003ctemplate #info-icon\u003e\n    \u003cInfoIcon /\u003e\n  \u003c/template\u003e\n  \u003ctemplate #warning-icon\u003e\n    \u003cWarningIcon /\u003e\n  \u003c/template\u003e\n\u003c/Toaster\u003e\n```\n\n### Close button\n\nAdd a close button to all toasts that shows on hover by adding the `closeButton` prop.\n\n```html\n\u003cToaster closeButton /\u003e\n```\n\n### Rich colors\n\nYou can make error and success state more colorful by adding the `richColors` prop.\n\n```html\n\u003cToaster richColors /\u003e\n```\n\n### Custom offset\n\nOffset from the edges of the screen.\n\n```html\n\u003cToaster offset=\"80px\" /\u003e\n```\n\n### On Close Callback\n\nYou can pass `onDismiss` and `onAutoClose` callbacks. `onDismiss` gets fired when either the close button gets clicked or the toast is swiped. `onAutoClose` fires when the toast disappears automatically after it's timeout (`duration` prop).\n\n```ts\ntoast('Event has been created', {\n  onDismiss: (t) =\u003e console.log(`Toast with id ${t.id} has been dismissed`),\n  onAutoClose: (t) =\u003e\n    console.log(`Toast with id ${t.id} has been closed automatically`)\n})\n```\n\n### Persisting toasts\n\nYou can change the duration of each toast by using the duration property, or change the duration of all toasts like this:\n\n```html\n\u003cToaster :duration=\"10000\" /\u003e\n```\n\n```ts\ntoast('Event has been created', {\n  duration: 10000\n})\n\nIf you want a toast to stay on screen forever, you can set the duration to `Infinity`.\n\n// Persisent toast\ntoast('Event has been created', {\n  duration: Infinity\n})\n```\n\n### Dismissing toasts programmatically\n\nTo remove a toast programmatically use `toast.dismiss(id)`.\n\n```ts\nconst toastId = toast('Event has been created')\n\ntoast.dismiss(toastId)\n```\n\nYou can also dismiss all toasts at once by calling `toast.dismiss()` without an id.\n\n```ts\ntoast.dismiss()\n```\n\n### Keyboard focus\n\nYou can focus on the toast area by pressing ⌥/alt + T. You can override it by providing an array of event.code values for each key.\n\n```html\n\u003cToaster hotkey=\"['KeyC']\" /\u003e\n```\n\n## Inspiration\n\n- [sonner](https://github.com/emilkowalski/sonner) - An opinionated toast component for React.\n\n## License\n\nMIT [@xiaoluoboding](https://github.com/xiaoluoboding)\n","funding_links":["https://github.com/sponsors/xiaoluoboding"],"categories":["Vue"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiaoluoboding%2Fvue-sonner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxiaoluoboding%2Fvue-sonner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiaoluoboding%2Fvue-sonner/lists"}