🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

sonner-web-component

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sonner-web-component

An opinionated toast web component, a port of @emilkowalski's Sonner.

latest
Source
npmnpm
Version
0.1.4
Version published
Weekly downloads
16
-27.27%
Maintainers
1
Weekly downloads
 
Created
Source

Sonner Web Component

A web component port of Sonner. No framework required — use it with Django, Rails, Laravel, htmx, Alpine.js, or plain HTML.

Installation

Add the script tag to your page:

<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"></script>

Or install via npm with your preferred package manager:

npm install sonner-web-component

Getting Started

Add <sonner-toaster> to your page.

<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"></script>

<sonner-toaster></sonner-toaster>

Render a toast.

<script type="module">
  import { toast } from "https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"
  toast("Hello!")
</script>

Usage

There are three ways to create toasts: server-rendered HTML, declarative data-toast-* attributes, and the JavaScript toast() API. window.toast is set by default, or you can import { toast } from the module.

Toaster

<sonner-toaster> is the custom element that manages and renders all toasts. Place it once on your page — everything else builds on it. Configure it with attributes.

<sonner-toaster position="top-center" theme="dark" rich-colors close-button></sonner-toaster>

Or from JavaScript:

toast.configure({ duration: 5000, position: "top-center" })

Each toaster renders into its own Shadow DOM. Styles are fully encapsulated — they won't leak into your page and your page's styles won't affect toasts.

Multiple toasters

You can place multiple <sonner-toaster> elements on a page, each with its own configuration. The global toast() API targets the first one — to reach others, call .add() on the element directly.

<sonner-toaster id="alerts" position="top-center" theme="dark"></sonner-toaster>
<sonner-toaster id="notifications" position="bottom-right"></sonner-toaster>

<script type="module">
  document.getElementById("alerts").add("error", "Something went wrong.")
</script>

API reference

AttributeTypeDefaultDescription
positionstringbottom-righttop-left, top-center, top-right, bottom-left, bottom-center, bottom-right
themestringsystemlight, dark, system
rich-colorsbooleanfalseColored backgrounds based on toast type
expandbooleanfalseExpand toasts by default
close-buttonbooleanfalseShow close button on toasts
invertbooleanfalseInvert default colors
durationnumber4000Auto-dismiss duration in ms
gapnumber14Gap between toasts in px
visible-toastsnumber3Max visible toasts in stack
offsetstring | number | object24pxDistance from viewport edge
mobile-offsetstring | number | object16pxDistance from viewport edge on mobile
dirstringltrText direction (ltr, rtl, auto)
windowbooleantrueSet window.toast globally. Use window="false" to opt out
flush-delaynumber200Delay in ms before consuming <sonner-toast> children after page load
burst-windownumber500Time window in ms — toasts arriving within this interval auto-expand the stack
burst-lingernumber3000How long in ms the stack stays expanded after a burst before collapsing

The element also exposes methods for creating and managing toasts directly. Use these to target a specific toaster when you have more than one.

MethodDescription
.add(level, message, options?)Create a toast. level is "success", "error", "info", "warning", "loading", or ""
.dismiss(id?)Dismiss one toast by ID, or all
.promise(promise, data)Create a promise toast
.configure(opts)Update configuration
.reset()Clear all toasts
.getToasts()Get all active toasts

Server-rendered

Nest <sonner-toast> elements inside <sonner-toaster>. They display as toasts on page load. Works with any templating language.

<sonner-toaster>
  <sonner-toast level="success">Item saved.</sonner-toast>
  <sonner-toast level="error">Something went wrong.</sonner-toast>
</sonner-toaster>

Declarative Triggers

Elements with data-toast-* attributes trigger toasts on click.

<button data-toast-success="Saved!">Save</button>
<button data-toast-error="Failed." data-toast-description="Please try again.">Delete</button>

Toast JavaScript API

You can call it with just a string, or provide an options object as the second argument.

toast("Hello!")
toast("Hello!", { description: "This is a description.", duration: 5000 })

Position

Override the toaster's default position on a per-toast basis. The toaster creates a separate group for each position.

toast.success("Saved!", { position: "top-center" })
toast.error("Failed.", { position: "bottom-right" })

Types

Each type renders a corresponding icon.

toast.success("Saved!")
toast.error("Something went wrong.")
toast.info("FYI.")
toast.warning("Careful.")
toast.loading("Working...")

Action and cancel buttons

Action renders a primary button, cancel renders a secondary button. Cancel always closes the toast. Action closes the toast unless you call event.preventDefault() in the onClick callback.

toast("File deleted", {
  action: { label: "Undo", onClick: () => restore() },
  cancel: { label: "Dismiss", onClick: () => {} },
})

Promise

Starts in a loading state and updates automatically after the promise resolves or fails. You can pass a function to the success/error messages to use the result.

toast.promise(fetch("/api/save"), {
  loading: "Saving...",
  success: "Saved!",
  error: "Failed to save.",
})

Dismiss

Each toast returns an ID you can use to dismiss it. Call without an ID to dismiss all toasts.

const id = toast.success("Saved!")
toast.dismiss(id)  // dismiss one
toast.dismiss()    // dismiss all

Reset

Clears all toasts but keeps the toaster on the page.

toast.reset()

Destroy

Removes the toaster element from the DOM entirely. A new one is created automatically on the next toast() call.

toast.destroy()

Get toasts

Returns all active toasts.

toast.getToasts()

API reference

OptionTypeDefaultDescription
descriptionstring-Secondary text below the title
durationnumber4000Auto-dismiss time in ms (Infinity to persist)
dismissiblebooleantrueWhether the toast can be swiped/dismissed
richColorsbooleantoaster defaultColored backgrounds based on toast type
closeButtonbooleantoaster defaultShow close button on this toast
invertbooleantoaster defaultInvert default colors for this toast
positionstringbottom-rightOverride position for this toast
idnumber-Reuse an ID to update an existing toast
htmlstring-Raw HTML content (trusted content only)
action{ label, onClick }-Action button
cancel{ label, onClick }-Cancel button
onDismissfunction-Called when dismissed by user
onAutoClosefunction-Called when dismissed by timer

Bridges

Bridges connect Sonner Web Component to other libraries. Each bridge is a side-effect import — add the script tag and it wires itself up. No configuration needed.

htmx

The htmx bridge listens for toast events on document, which is how htmx dispatches events from the HX-Trigger response header (they bubble up from document.body). Set the header on any htmx response and toasts appear automatically.

<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.x.x/dist/htmx.min.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/bridges/htmx.js"></script>

<sonner-toaster></sonner-toaster>

<button hx-post="/save" hx-swap="none">Save</button>

Your server sets the HX-Trigger response header with a toast event:

HTTP/1.1 200 OK
HX-Trigger: {"toast": {"level": "success", "message": "Saved!"}}

Multiple toasts can be sent at once:

HTTP/1.1 200 OK
HX-Trigger: {"toast": [{"level": "success", "message": "Saved!"}, {"level": "info", "message": "Notified team."}]}

fetch

The fetch bridge lets your server trigger toasts from any fetch call — form submissions, API requests, or anything else that uses fetch. It also works as a way to connect an SPA to a server-rendered page that hosts the toaster. It monkey-patches window.fetch to read the X-Toasts header from every response. If the header is present, the toasts are rendered automatically.

<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/bridges/fetch.js"></script>

<sonner-toaster></sonner-toaster>

<script type="module">
  // toasts from the response header appear automatically
  const response = await fetch("/api/save", { method: "POST" })
</script>

Your server includes the X-Toasts response header:

HTTP/1.1 200 OK
X-Toasts: [{"level": "success", "message": "Saved!"}]

The level field accepts "success", "info", "warning", or "error". The response body is unaffected — the bridge only reads the header.

Alpine.js

The Alpine.js bridge registers a $toast magic that exposes the full toast API inside Alpine expressions.

<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/index.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/sonner-web-component@0.1.4/dist/bridges/alpine.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>

<sonner-toaster></sonner-toaster>

<div x-data>
  <button @click="$toast.success('Saved!')">Save</button>
  <button @click="$toast.error('Failed.')">Delete</button>
  <button @click="$toast('Hello!', { description: 'A plain toast.' })">Toast</button>
</div>

The $toast magic supports all the same methods: $toast.success(), $toast.error(), $toast.info(), $toast.warning(), $toast.loading(), $toast.promise(), and $toast.dismiss().

License

Sonner Web Component is licensed under the MIT license. See the LICENSE file for more information.

Sonner is licensed under the MIT license and is Copyright (c) 2023 Emil Kowalski.

Keywords

toast

FAQs

Package last updated on 24 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts