User Identification
By default, TraceLog tracks visitors anonymously using session IDs. When a user logs in, you can associate their anonymous session with a known identity using tracelog.identify().
Basic Usage
Call identify() after the user successfully logs in:
import { tracelog } from '@tracelog/lib';
// After successful login
tracelog.identify('user_123');
// With optional traits
tracelog.identify('user_123', {
plan: 'pro',
role: 'admin',
cohort: 'enterprise'
});
All subsequent events in the session will include this identity. Events still in the send queue will also be tagged, but events already transmitted are not retroactively updated.
Signature
tracelog.identify(userId: string, traits?: Record<string, string>): void
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | Your internal user identifier |
traits | object | No | Optional user properties (plan, role, segment, etc.) |
On Logout: Reset Identity
When a user logs out, clear their identity so subsequent anonymous activity doesn't get attributed to them:
// On logout
await tracelog.resetIdentity();
resetIdentity() generates a new anonymous UUID and starts a fresh session. It is async because the new session start event is sent as part of the reset.
Full Login / Logout Flow
// On login
async function onLogin(user) {
tracelog.identify(user.id, {
plan: user.subscription.plan,
createdAt: user.createdAt
});
}
// On logout
async function onLogout() {
await tracelog.resetIdentity();
}
Privacy: Avoid PII in User IDs
Do not use email addresses or other PII as the user ID. Use your internal user ID (a database ID or UUID).
// Do NOT use
tracelog.identify(user.email); // PII — email address
tracelog.identify(user.phoneNumber); // PII — phone number
// Use instead
tracelog.identify(user.id); // Internal database ID
tracelog.identify(user.uuid); // UUID
If you need to use a hash instead of a raw ID, use SHA-256:
async function getAnonymousUserId(rawId: string): Promise<string> {
const encoder = new TextEncoder();
const data = encoder.encode(rawId + 'your-app-salt');
const buffer = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
const hashedId = await getAnonymousUserId(user.id);
tracelog.identify(hashedId);
Traits
Traits are key-value pairs that describe the user. They are attached to every event going forward and can be used to segment analytics.
Trait values must be strings. Non-string values are silently filtered out.
Useful traits:
plan— current subscription tier ('free','growth','pro')role— user role in your app ('admin','member','viewer')cohort— user segment or A/B test grouptenure— days since account creation ('45')
tracelog.identify('user_123', {
plan: 'pro',
role: 'admin',
cohort: 'beta-2024',
tenure: '45'
});
Traits should not include PII (email, name, phone, address).
Difference from Global Metadata
identify() and mergeGlobalMetadata() both attach data to events, but they serve different purposes:
identify() | mergeGlobalMetadata() | |
|---|---|---|
| Purpose | Link session to a known user | Attach arbitrary context to events |
| User ID | Stored as userId in the session | Not stored as an identity |
| Persistence | Persists in localStorage until explicitly reset | Replaced or merged at runtime |
| Traits | User-level properties | Environment or app-level properties |
Use identify() when you want events attributed to a specific user. Use mergeGlobalMetadata() for environment context (app version, feature flags, A/B experiments).
Next Steps
- Global Metadata — Attach environment and app context to all events
- Goals & Conversions — Measure conversion rates by user segment