Install
Three ways to add sonner-wc to a page.
From a CDN
Drop one <script> tag and one element into any HTML page:
<script type="module" src="https://unpkg.com/sonner-wc/dist/sonner-wc.bundle.js"><\/script>
<sonner-toaster position="bottom-right" theme="system"></sonner-toaster>
<script type="module">
import { toast } from 'https://unpkg.com/sonner-wc';
document.querySelector('button').addEventListener('click', () => toast.success('Hello!'));
</script> From npm
npm install sonner-wc # or: bun add / pnpm add / yarn add Then import it once — the side-effect registers the two custom elements:
import { toast } from 'sonner-wc';
// <sonner-toaster> and <sonner-toast> custom elements are
// registered as a side effect of the import. Where to place it
Put <sonner-toaster> once, near the end of <body>. It uses position: fixed, so the exact spot in the DOM rarely matters — with one
caveat.
Heads up
Ancestors with transform, filter, perspective, backdrop-filter, will-change (any of those), or contain: paint/layout/strict become the containing block for position: fixed, so the toaster anchors to them (and can get clipped by overflow: hidden) instead of the viewport.
Fix: move <sonner-toaster> to the document root.
Framework integration
React
If you’re writing React, use the original Sonner — it’s the same UX, designed for React from the start, with proper JSX types and refs. We’re a port of Sonner, not a replacement.
Vue
<script setup>
import 'sonner-wc';
import { toast } from 'sonner-wc';
</script>
<template>
<sonner-toaster position="bottom-right" theme="system" />
<button @click="toast.success('Saved!')">Save</button>
</template> Svelte
<script>
import 'sonner-wc';
import { toast } from 'sonner-wc';
</script>
<sonner-toaster position="bottom-right" theme="system" />
<button on:click={() => toast.success('Saved!')}>Save</button>