VITE_ vs REACT_APP_).
Setup
1
Install the SDK
Add Then add your publishable key to Your key is under Settings → API Keys in the dashboard.
@wendung/sdk to your project..env:.env
2
Initialize at app startup
Call
init() at your entry point, before rendering. This starts the flush loop and registers the page-unload listeners.src/main.tsx
init() is idempotent. React Strict Mode double-invokes effects in development, and Vite’s hot module replacement can re-run your entry file. Both are handled, with no duplicate listeners or flushes.3
Track funnel steps
Call
step() whenever a user completes a step in one of your funnels. The name should match a step defined in the dashboard. The second argument is an optional object of properties.src/components/SignupForm.tsx
4
Identify users after login
Once you know who the user is, call The identity is saved in
identify() with a stable user ID and any traits you want on the events that follow.localStorage and restored by init(), so a reload keeps the user identified. Each identify() call replaces the identity and traits wholesale, with no merging, and reset() clears it. Re-identify anyway once your app has checked its own session, so traits stay current.5
Turn on pageview tracking
SPAs do not fire page loads on navigation, and you do not need to emit anything yourself: with For aggregate pageviews while consent is pending, use
trackPageviews: true the SDK records the initial load and every React Router navigation.src/main.tsx
trackPageviews: 'auto' and pass the current consent state. Call Wendung.setConsent('granted') to switch to full analytics, or 'denied' to stop collection. See the consent guide for saving and restoring the choice.Register the hostname under Sites in the dashboard to see the traffic. If your router changes the URL without the history API, call page() after each navigation instead. Pageviews use a separate monthly allowance from events; see the web analytics guide.6
Handle logout
Call
reset() when the user signs out. It flushes pending events under the old identity, clears the user ID and traits, and starts a new session.Advanced: teardown in micro-frontends
Most SPAs never calldestroy(). The SDK lives as long as the page does, and the queue drain on page hide handles the final send.
The exception is a micro-frontend shell that loads and unloads sub-applications at runtime. There, call destroy() in your cleanup hook to stop the flush loop, remove the listeners, and send one last batch:
destroy(), call init() again before using any other method.
What’s next
Create your first funnel
Turn your tracked step names into a funnel in the dashboard.
API reference
Every option accepted by
init(), identify(), step(), and reset().