Skip to Content
DocsSDKsWebIdentity & Sessions

Identity & Sessions

Link anonymous browsing to known users and manage session lifecycle. Identity is what turns anonymous page views into actionable user profiles.

The sign-in flow

This is the pattern every web app should follow:

import { init, track, identify, reset } from '@poluruprvn/pug-web' init('PROJECT_ID', { apiKey: 'KEY', endpoint: 'https://api.pug.sh' }) // 1. Anonymous browsing — events accumulate against anonymous profile track('page_view') track('add_to_cart', { product_id: 'sku-123' }) // 2. User signs in — merge anonymous history into identified profile async function onSignIn(user: { id: string; email: string; plan: string }) { identify(user.id, { email: user.email, plan: user.plan, name: user.name }) track('login', { method: 'email' }) } // 3. User signs out — clear identity, start fresh anonymous session function onSignOut() { reset() track('page_view') // new anonymous session }

After identify(), all prior anonymous events (page views, cart additions) appear on the identified profile in Profiles.

Identify

Link anonymous activity to a known user:

import { identify } from '@poluruprvn/pug-web' identify('user-123', { email: 'user@example.com', plan: 'pro', company: 'Acme Inc', signed_up_at: '2026-01-15' })

Rules:

  • Call identify() as early as possible after sign-in — before any post-login track() calls
  • Use a stable, unique external ID (your database user ID, not email)
  • Traits are merged — subsequent identify() calls add/update traits without removing existing ones
  • The same external ID always resolves to the same profile

Identify on every page load for logged-in users

If your app restores sessions from cookies (most apps do), call identify() on every page load for authenticated users:

// On app init, after checking auth state if (currentUser) { identify(currentUser.id, { email: currentUser.email, plan: currentUser.plan }) }

This ensures returning visitors are recognized immediately, not just after an explicit sign-in event.

Reset

Clear identity on sign-out or account switch:

import { reset } from '@poluruprvn/pug-web' reset()

reset():

  • Clears the stored identity
  • Starts a new anonymous session
  • Does not delete the identified profile — it remains in the dashboard

Always call reset() before a different user signs in on a shared device.

Sessions

Sessions group events within a single visit.

How sessions work

First event → session ID created Events within 30 min → same session ID (timeout configurable) 30 min idle → session expires Next event → new session ID (identity preserved)

The Web SDK:

  • Creates a session ID on the first event after init
  • Extends the session on each event within the timeout window
  • Syncs session ID across browser tabs via localStorage

Configure timeout in init:

init('PROJECT_ID', { apiKey: 'KEY', session: { timeoutMs: 30 * 60 * 1000 } // 30 minutes })

Force session rotation

Start a new session without clearing identity — useful after explicit “new visit” signals:

import { rotate } from '@poluruprvn/pug-web' rotate()
FunctionClears identityNew session ID
rotate()NoYes
reset()YesYes

Alias

Merge two profile IDs server-side — for cases where a user had separate profiles before and after a migration:

anonymous-abc ──alias──▶ user-123 legacy-id-xyz ──alias──▶ user-123

Alias is a server-side operation via ProfilesSDKService. Contact your backend team or use the Profiles API directly. The Web SDK does not expose a client-side alias function.

Backend

Identify calls ProfilesSDKService.Identify via Connect RPC:

POST /profiles.v1.ProfilesSDKService/Identify Authorization: Bearer <sdk-api-key> x-project-id: <project-id>

Profile writes are async — expect a few seconds before the profile appears in dashboard search.

Common mistakes

MistakeConsequenceFix
Never calling identify()All users stay anonymousCall on sign-in and page load for auth’d users
Using email as external IDID changes if email changesUse database user ID
Skipping reset() on sign-outNext user’s events attributed to previous userAlways reset on sign-out
Calling identify() before init()Silent failureInit first
Different IDs across platformsDuplicate profilesUse same ID scheme on web and mobile

Verify identity

  1. Browse anonymously — check Profiles for anonymous profile with events
  2. Sign in — call identify()
  3. Refresh Profiles — search by external ID; pre-login events should appear
  4. Sign out — call reset(); new anonymous profile created

Further reading

Last updated on