Plain JavaScript

Any site, any framework, no build step: one ES-module script tag. This is also the path for Vue, Angular, and Svelte until their first-class providers land.

The script tag

<!-- Before </head>. No build step required; any site, any framework. -->
<script type="module">
  import { initSonder } from "https://cdn.jsdelivr.net/npm/@sonderhq/sdk@0.1/+esm";

  initSonder({ writeKey: "snd_pk_your_write_key", buildId: "site@v42" });
</script>

Running npx sonder-init <write_key> in a folder with an index.html makes these edits for you and verifies events flow.

Bundling instead? npm install @sonderhq/sdk and call initSonder from your entry module; the package is pure ESM with zero runtime dependencies.

Using the client

initSonder returns the client and also exposes it as window.sonder, which is the convenient handle outside a module system:

window.sonder.track("newsletter_signup");
window.sonder.identify("user-8f31", { plan: "free" });

Getting good labels

Autocapture names elements by meaning: aria-label, then visible text, then name/placeholder, then the associated <label>. Two attributes give you control:

<!-- Everything inside a data-sonder-mask subtree reports [masked] as its
     label, and its text never appears in state probes. -->
<section data-sonder-mask>
  <h2>Account balance</h2>
  <p>$12,340.55</p>
  <button>Withdraw</button> <!-- captured as: click "[masked]" (button) -->
</section>

<!-- Give an unstable or icon-only control a stable, human name. -->
<button data-sonder-name="Close checkout">×</button>
  • data-sonder-name: a stable, human name for icon-only or generated controls.
  • data-sonder-mask: force-mask a subtree; its text never reaches labels or state probes.

Framework roadmap

FrameworkStatus
React, Next.jsshipped
Plain JS / any framework via script tagshipped
Vue, Angular, Svelte providersroadmap · script tag works today
React Nativeroadmap