{"id":22489498,"url":"https://github.com/cssninjaStudio/nuxt-toaster","last_synced_at":"2025-08-02T21:32:58.352Z","repository":{"id":59980960,"uuid":"540218154","full_name":"cssninjaStudio/nuxt-toaster","owner":"cssninjaStudio","description":"🔔 A simple toaster handler for Nuxt.js","archived":false,"fork":false,"pushed_at":"2025-07-18T14:16:18.000Z","size":597,"stargazers_count":36,"open_issues_count":2,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-18T17:22:49.513Z","etag":null,"topics":["notification","nuxt","toast","typescript","vue"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@cssninja/nuxt-toaster","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cssninjaStudio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"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},"funding":{"github":"cssninjaStudio"}},"created_at":"2022-09-23T00:24:38.000Z","updated_at":"2025-07-18T14:16:23.000Z","dependencies_parsed_at":"2024-10-03T12:37:43.848Z","dependency_job_id":"8ad3e97a-7d5a-46d9-abe1-70224a078dce","html_url":"https://github.com/cssninjaStudio/nuxt-toaster","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/cssninjaStudio/nuxt-toaster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cssninjaStudio%2Fnuxt-toaster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cssninjaStudio%2Fnuxt-toaster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cssninjaStudio%2Fnuxt-toaster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cssninjaStudio%2Fnuxt-toaster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cssninjaStudio","download_url":"https://codeload.github.com/cssninjaStudio/nuxt-toaster/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cssninjaStudio%2Fnuxt-toaster/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268456838,"owners_count":24253296,"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","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["notification","nuxt","toast","typescript","vue"],"created_at":"2024-12-06T17:19:59.001Z","updated_at":"2025-08-02T21:32:58.065Z","avatar_url":"https://github.com/cssninjaStudio.png","language":"TypeScript","readme":"# @cssninja/nuxt-toaster\n\n🔔 A simple toaster (notifier) handler for Nuxt.js\n\n[![npm](https://img.shields.io/npm/v/@cssninja/nuxt-toaster.svg)](https://www.npmjs.com/package/@cssninja/nuxt-toaster)\n\n## Features\n\n- 🔧 Unstyled by default\n- 🧩 Render any component as a toast\n- 🎨 Fully customizable\n- 🪄 Simple to use\n\n\n## Installation\n\n1. Add `@cssninja/nuxt-toaster` dependency to your project\n```bash\n# Using pnpm\npnpm add -D @cssninja/nuxt-toaster\n\n# Using yarn\npnpm add -D @cssninja/nuxt-toaster\n\n# Using npm\nnpm install --save-dev @cssninja/nuxt-toaster\n```\n\n2. Add `@cssninja/nuxt-toaster` to the `modules` section of `nuxt.config.js`\n\n```ts\nexport default defineNuxtConfig({\n  modules: [\n    '@cssninja/nuxt-toaster'\n  ]\n})\n```\n\n## Basic Usage\n\n### Show a toast\n\n```ts\n// get the ninjaToaster instance\nconst { $nt } = useNuxtApp()\n\n// show a toast with a string as content\n$nt.show('Hello world')\n```\n\n### Show a toast with a custom component\n\n```ts\n// define or import a component\nconst MyToast = defineComponent({\n  /* ... */\n})\n\n// get the ninjaToaster instance\nconst { $nt } = useNuxtApp()\n\n// show a toast with render function as content\n$nt.show(() =\u003e h(MyToast))\n```\n\n## Configuration\n\n### Using `ninjaToaster.show` options\n```ts\n// get the ninjaToaster instance\nconst { $nt } = useNuxtApp()\n\n$nt.show({\n  /**\n   * The content of the toast, can be a render function (a.k.a stateless component)\n   * \n   * @type {string | number | Record\u003cstring, any\u003e | (() =\u003e Component)}\n   * @required\n   */\n  content: 'Hello world',\n\n  /**\n   * The duration of the toast\n   * \n   * @default 5000\n   */\n  duration: 5000,\n\n  /**\n   * Pause the duration timer on hover, or focus\n   * \n   * @default true\n   */\n  pauseOnHover: true,\n\n  /**\n   * Whereas the toast can be closed on click,\n   * or on pressing Enter/Space keys when focused\n   * \n   * @default true\n   */\n  dismissible: false,\n\n  /**\n   * Maximum number of toasts to show \n   * on the same `theme.containerId`\n   * \n   * @default Infinity\n   */\n  maxToasts: 5,\n\n  /**\n   * Transition property for the toast\n   * \n   * @see https://vuejs.org/api/built-in-components.html#transition\n   */\n  transition: {\n    name: 'fadeIn',\n  },\n\n  /**\n   * The theme used for the toast\n   */\n  theme: {\n    /**\n     * The container id where the toast will be rendered\n     * If not exists, it will be created automatically\n     * \n     * @default 'nt-container'\n     */\n    containerId: 'nt-container',\n    /**\n     * The class name for the toaster container (applyed to toast container)\n     * \n     * @type {string | string[]}\n     * @default ''\n     */\n    containerClass: 'nt-container-class',\n    /**\n     * The class name for the toast wrapper (applyed to each toast)\n     * \n     * @type {string | string[]}\n     * @default ''\n     */\n    wrapperClass: 'nt-wrapper-class',\n  }\n})\n```\n\n\u003e This will create a toast with the following HTML structure:\n\u003e ```html\n\u003e \u003cbody\u003e\n\u003e   \u003c!-- ... --\u003e\n\u003e   \u003cdiv id=\"nt-container\" class=\"nt-container-class\"\u003e\n\u003e     \u003cdiv\n\u003e       class=\"nt-wrapper-class\"\n\u003e       role=\"alert\"\n\u003e       tabindex=\"0\"\n\u003e     \u003e\n\u003e       Hello world\n\u003e     \u003c/div\u003e\n\u003e   \u003c/div\u003e\n\u003e \u003c/body\u003e\n\u003e ```\n\u003e **note:** the `theme` property is used to customize the toaster behavior. Each `theme.containerId` will have their own context (e.g. the `maxToasts` will count how many toaster are visible in the container with matching id).\n\n\n### Using `toaster` app config\n\nTo avoid to repeat yourself, you can set defaults values for ninjaToaster.show method in the nuxt `app.config.ts` at the root of your project.\n\n```ts\n// app.config.ts\nexport default defineAppConfig({\n  toaster: {\n    // default options for ninjaToaster.show\n  }\n})\n```\n\n### Using a custom plugin\n\nBy default, the module create an instance of `ninjaToaster` and inject it in the nuxt context in `useNuxtApp().$nt`.  \n\nYou can create your own instance and inject it in the context by using a custom plugin. Here we are using tailwindcss to style the toast.\n\n1. Disable default plugin in `nuxt.config.ts` module options\n```ts\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: [\n    '@cssninja/nuxt-toaster'\n  ],\n  toaster: {\n    // disable the default plugin \n    installPlugin: false\n  }\n})\n```\n\n2. Create a custom toast component\n```vue\n\u003cscript setup lang=\"ts\"\u003e\n// components/MyToast.vue\nconst props = defineProps\u003c{\n  title: string\n  message?: string\n  type: 'info' | 'error'\n}\u003e()\n\nconst {\n  isHovered,\n  isActive,\n  timer,\n  duration,\n  click,\n  close,\n} = useNinjaToasterState()\n\nconst {\n  percent,\n  endAt,\n  closeIn\n} = useNinjaToasterProgress()\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cdiv\n    class=\"rounded p-4\"\n    :class=\"[\n      props.type === 'info' \u0026\u0026 'bg-indigo-600 text-indigo-500'\n      props.type === 'error' \u0026\u0026 'bg-rose-600 text-rose-500'\n    ]\"\n  \u003e\n    \u003ch1\u003e{{ props.title }}\u003c/h1\u003e\n    \u003cp v-if=\"props.message\"\u003e{{ props.message }}\u003c/p\u003e\n    \u003cbutton @click=\"close()\"\u003eClose\u003c/button\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\n3. Create a custom plugin\n\n```ts\n// plugins/toaster.ts\nimport MyToast from '~/components/MyToast.vue'\n\ninterface ToasterOptions {\n  message: string\n  title?: string\n}\n\nexport default defineNuxtPlugin(() =\u003e {\n  // define or import a theme\n  const theme = {\n    containerId: 'nt-container-bottom-right',\n    containerClass: [\n      'absolute',\n      'inset-0',\n      'pointer-events-none',\n      'p-4',\n      'flex',\n      'flex-col-reverse',\n      'items-start',\n      'gap-2'\n    ],\n    wrapperClass: [\n      'pointer-events-auto',\n      'cursor-pointer',\n    ],\n  }\n\n  // set default show options here\n  const nt = createNinjaToaster({\n    theme,\n    maxToasts: 5,\n    transition: {\n      enterActiveClass: 'transition duration-300 ease-out',\n      enterFromClass: 'transform translate-x-full opacity-0',\n      enterToClass: 'transform translate-x-0 opacity-100',\n      leaveActiveClass: 'transition duration-300 ease-in',\n      leaveFromClass: 'transform translate-x-0 opacity-100',\n      leaveToClass: 'transform translate-x-full opacity-0'\n    }\n  })\n\n  const toaster = {\n    info (options: ToasterOptions) {\n      nt.show(() =\u003e h(MyToast, {\n        ...options,\n        type: 'info'\n      }))\n    },\n    async error (options: ToasterOptions) {\n      // wait for the toast to be mounted\n      const { el, close } = await nt.show(() =\u003e h(MyToastError, {\n        ...options,\n        type: 'error'\n      }))\n\n      // focus the toast once it's mounted\n      el.focus()\n    },\n    close() {\n      // close all toasts\n      nt.closeAll()\n\n      // or close toasts in a specific containerId\n      nt.close('nt-container-bottom-right') \n\n      // or close toasts using a theme\n      nt.close(theme)\n    },\n  }\n\n  return {\n    provide {\n      toaster\n    }\n  }\n})\n```\n\n3. Use your `toaster` instance in your app\n```ts\n// pages/index.vue\nconst { $toaster } = useNuxtApp()\n\n$toaster.info({\n  title: 'Hello world',\n  message: 'This is a toaster info message'\n})\n$toaster.error({\n  title: 'Hello world',\n  message: 'This is a toaster error message'\n})\n```\n\n## Theming\n\n### Minimal CSS theme\n\n```css\n#nt-container {\n  /* make container fit the screen */\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  overflow: hidden;\n  z-index: 100;\n  pointer-events: none;\n\n  /* position the toasts using flexbox */\n  display: flex;\n  \n  /**\n   * position all toasts in bottom of the screen \n   * - use \"flex-direction: column;\" to position in top screen\n   */\n  flex-direction: column-reverse;\n\n  /**\n   * align all toasts to the center\n   * - use \"align-items: start\" to aling to the left\n   * - use \"align-items: end\" to aling to the right\n   */\n  align-items: center;\n\n  /* add some space between toasts and screen */\n  padding: 2rem;\n  gap: 1rem;\n}\n\n#nt-container [role='alert'] {\n  /* allow toasts to be interactive */\n  pointer-events: auto;\n\n  /* add styles to toasts */\n  padding: 1rem;\n  border-radius: 0.5rem;\n  background-color: #fff;\n  box-shadow: 0 0 1rem rgba(0, 0, 0, 0.1);\n}\n\n\n@media (max-width: 767px) {\n  #nt-container {\n    /* fit toasts to screen on mobile */\n    padding: 0;\n  }\n}\n\n```\n\n\n## Development\n\n- Run `npm run dev:prepare` to generate type stubs.\n- Use `npm run dev` to start [playground](./playground) in development mode.\n","funding_links":["https://github.com/sponsors/cssninjaStudio"],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FcssninjaStudio%2Fnuxt-toaster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FcssninjaStudio%2Fnuxt-toaster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FcssninjaStudio%2Fnuxt-toaster/lists"}