- Debug logs (
[Wendung] ...): opt-in viadebug: true, trace normal SDK activity. - Warnings (
[Wendung - Warning] ...): always on, emitted when the SDK hits something unexpected.
Enable debug mode
debug: true, the SDK logs:
Warning messages
Warnings are emitted regardless of thedebug setting. This is the complete list.
Invalid configuration makes
init() throw instead of warning; see init() options.
Verifying your integration
After your firststep() call, confirm events are flowing:
- Network tab. Filter for
eventsin DevTools. APOSTto the ingest endpoint appears within 5 seconds (sooner if the batch fills). A 2xx response means the batch was accepted. - Dashboard. Your user appears in the Recent identities card on the Overview within a minute.
- Debug mode.
debug: trueshows the init log, queued events, and flushes in the console. - Pageviews. With
trackPageviews: true, the site appears on the Sites page within a minute of the first pageview, and the green badge next to its name counts visitors from the last five minutes.
Common issues
Events are not being sent
Events are not being sent
Most common causes, in order:
init()wasn’t called, or ran after the firststep(). Initialize at app startup.- The
apiKeyis wrong or deactivated. Check Settings → API Keys in your dashboard. - A 4xx response is dropping your batches. Look for
[Wendung - Warning] Endpoint rejected batch batchId=... with status 401; dropping events. - The origin isn’t allowed. A
403means the page’s origin is missing from Settings → Allowed origins. A new project rejects every origin until you add one. - An ad-blocker or privacy extension is blocking the request. Blocked requests show as
(blocked)in the Network tab. - Check
Wendung.getConsent()in the console.deniedstops all collection.pendingdrops custom events and identification; it sends only aggregate pageviews whentrackPageviewsis'auto'. See the consent guide.
'Call .init() first' error
'Call .init() first' error
Every method except
init() and getConsent() throws [Wendung] Call .init() first when the SDK isn’t initialized. Usual causes:- A module calls an SDK method at import time, before your entry file runs
init(). - In Next.js, a Server Component or Route Handler used the SDK. It is browser-only; move the call into a Client Component.
Events sent near page unload aren't arriving
Events sent near page unload aren't arriving
On
visibilitychange (hidden) and pagehide, the SDK drains the whole queue with parallel fetch requests using keepalive, so unload delivery normally needs no extra work. If events still go missing:- A custom unload flow in your app may preempt the SDK’s listeners. Call
sendBeacon()from your own handler to drain the queue. - Mobile Safari is aggressive about killing background tabs. Some event loss on mobile is unavoidable.
Endpoint is rejecting requests with 4xx
Endpoint is rejecting requests with 4xx
The SDK drops the batch on any 4xx response and never retries it. Check:
401 Unauthorized: theapiKeyis wrong, disabled, or belongs to a different project.403 Forbidden: the request’s origin isn’t on the project’s allowed origins list.429 Too Many Requests: the monthly event quota is used up, or you’ve hit your plan’s rate limit. Check usage in the dashboard.400 Bad Request: the payload shape doesn’t match the ingest endpoint, usually a self-hosted version mismatch.
Events arrive in production but not from localhost
Events arrive in production but not from localhost
Only origins on the allowed origins list can send events, so
http://localhost:3000 is rejected unless you added it. The ingest endpoint answers 403 and the SDK logs Endpoint rejected batch batchId=... with status 403; dropping events.Turn on Dev mode in Settings → Allowed origins. For the next 24 hours the project also accepts loopback origins (localhost, *.localhost, 127.0.0.0/8, [::1], on any port). It switches itself off after that.The change can take a few minutes to reach the ingest endpoint. Private network addresses such as 192.168.1.42 are not covered, so testing from a phone on the same Wi-Fi still needs that origin on the allowed list. Requests without an Origin header, such as curl or server-side scripts, are always rejected.Duplicate events under React Strict Mode
Duplicate events under React Strict Mode
init() is safe to call twice: each call tears down the previous instance, so Strict Mode won’t duplicate timers or listeners.Duplicate step() events usually come from calling step() in a useEffect, which Strict Mode runs twice in development. Either move the call into an event handler, or guard with a ref:Pageviews are not showing
Pageviews are not showing
trackPageviewsis off. Usetruefor pageviews after consent, or'auto'for aggregate pageviews while pending and full pageviews after consent.deniedstops both. See consent.- The hostname is not registered. Pageviews are stored for every hostname, but the reports are per site: add it under Sites in the dashboard, or open All sites.
- The workspace is on the free plan, which has no pageview allowance. Web analytics needs a paid plan.
- The monthly pageview allowance is used up. The ingest endpoint still answers
202but reports the pageviews asdropped, and the Sites page shows the quota state. Yourstep()events keep flowing. - The request was rejected entirely. A
403means the origin is not on the allowed origins list; see the issue above.
Pageviews arrive but visitors stay at zero
Pageviews arrive but visitors stay at zero
With
trackPageviews: 'auto' and pending consent, this is expected. Aggregate pageviews contain no visitor or session identifiers. They increase pageview totals without increasing unique visitors, current visitors, or sessions. Bounce rate and other session metrics describe consented traffic only.Changing the configuration does not remove earlier consented visitors from the selected date range. Check the new request body for collection: 'aggregate' and no identity or sessionId. See aggregate pageviews.Events are attributed to the wrong user
Events are attributed to the wrong user
identify()replaces the identity but doesn’t start a new session, so events recorded between logins can share a session ID. Callreset()on every logout.- Traits carrying over from a previous login also mean a missing
reset()at logout.
Still stuck?
Reach out to support with:- Your project ID (dashboard, Settings → API Keys)
- A console dump with
debug: trueenabled - The request/response from your Network tab for a failing event