Auth integration recipes
This page collects copy-pasteable recipes for each widget auth mode against the most common backend and identity-provider stacks. The conceptual reference is in authentication overview; the per-mode details are under each auth-mode page.TL;DR
backendToken— your backend exposes a token endpoint; recipes per backend framework below.firebase— your frontend reads the Firebase ID token; minimal backend involvement.PubliclySignedJwt— your frontend reads the IDP’s session token; configured server-side in the dashboard.none— local dev only; no auth.
Backend Token recipes
Node — Express
Node — Fastify
Node — NestJS
PHP — Laravel
Python — Django
hashlib.sha256((user_id + auth_secret).encode()).hexdigest(). The hash format is the same as client.generateHashedToken() in the Node/Java/PHP SDKs.
Ruby — Rails
Java — Spring
Frontend consumption
Pair any of the backend recipes above with this frontend snippet:Firebase recipes
Web client
Re-mount on token refresh
Publicly-Signed JWT recipes
PubliclySignedJwt is configured server-side via the dashboard. The frontend just reads the IDP session token. Common providers:
Auth0
Clerk
Cognito
Supabase Auth
notificationCenterSetup dev-task captures the JWKS URL + claim paths once per environment — the same frontend code works regardless of provider once the dashboard is configured. See publicly-signed JWT for the dashboard side.
FAQ
Auth0 — which claims should I configure in the dashboard?
Auth0 — which claims should I configure in the dashboard?
By default, Auth0 puts the user id in
sub and the email in email (when the email scope is requested). Set paths.id = "sub" and paths.email = "email". With Auth0’s namespaced custom-claims pattern, use the namespaced paths instead.Clerk — same?
Clerk — same?
Clerk puts the user id in
sub. Email needs to be added via a Clerk session token template — Clerk doesn’t include it by default. Either add email to the template, or configure paths.email to the metadata path you use.Supabase Auth — anonymous users?
Supabase Auth — anonymous users?
Supabase Auth supports anonymous users with a stable
user.id and a valid JWT. PubliclySignedJwt works for them; bridge to a real identity later if your campaigns expect it.`'none'` safe on staging?
`'none'` safe on staging?
Only if staging is behind your VPN / SSO and not customer-facing. The threat model with
'none' is “anyone with the API key plus a userId can read that user’s inbox” — fine inside a controlled environment, never on the open internet.JWT works locally, fails on prod — what changed?
JWT works locally, fails on prod — what changed?
Cross-environment IDP config. Your dev environment is probably wired to dev IDP credentials and a dev JWKS URL; prod needs the prod equivalent. Compare the dashboard auth config side-by-side; most “works on dev only” cases trace to one stale field.
User has the bell but no notifications — auth or audience?
User has the bell but no notifications — auth or audience?
state.isReady === true means auth succeeded. If unreadCount is 0, the auth is fine but no message reached this userId. Check that your campaign’s orchestrator emits this exact userId as a recipient identifier — most “empty bell” cases are auth working + recipient mismatch.See also
Authentication overview
The four-mode model and when to pick each.
Backend tokens
client.generateHashedToken end-to-end.Firebase auth
Pass a Firebase ID token to the widget.
Publicly-signed JWT
Auth0 / Clerk / Cognito / Supabase setup.