User Identity
Learn how to track anonymous users and link them to identified users for accurate analytics.
Overview
Kitbase tracks users using two identifiers:
| Identifier | Description |
|---|---|
anonymous_id | Auto-generated UUID for anonymous users |
user_id | Your user identifier (after login/signup) |
Anonymous Tracking
The SDK automatically generates and persists an anonymous ID for tracking users before they log in:
// Track anonymous user (anonymous_id is automatically included)
await kitbase.track({
channel: 'marketing',
event: 'Landing Page Viewed',
icon: '👀',
});
// Get the current anonymous ID
const anonymousId = kitbase.getAnonymousId();
// => "550e8400-e29b-41d4-a716-446655440000"Storage
The anonymous ID is persisted in storage (localStorage by default) to maintain consistency across page reloads:
const kitbase = new Kitbase({
token: '<YOUR_API_KEY>',
storage: localStorage, // Default
storageKey: 'kitbase_anonymous_id', // Default
});
// Disable storage (anonymous ID regenerated each session)
const kitbase = new Kitbase({
token: '<YOUR_API_KEY>',
storage: null,
});Identity Resolution
Link anonymous users to identified users using the identify() function. This enables accurate Monthly Active User (MAU) calculations.
The identify() Function
await kitbase.identify({
userId: 'user-123',
traits: {
email: 'user@example.com',
name: 'John Doe',
plan: 'premium',
},
});| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | Unique user identifier |
traits | object | No | User properties (email, name, etc.) |
How It Works
Anonymous tracking: When a user first interacts with your app, the SDK generates an anonymous ID internally and attaches it to all events.
Explicit identification: When the user logs in or signs up, you call
identify()to link the anonymous ID to a user ID.Deduplication: Once linked, all previous anonymous events are attributed to the identified user, ensuring accurate user counts.
Example Flow
// Session 1: Track anonymous user
await kitbase.track({
channel: 'engagement',
event: 'Page View',
});
// → tracked with anonymous_id: "anon_abc123"
await kitbase.track({
channel: 'engagement',
event: 'Add to Cart',
});
// → tracked with anonymous_id: "anon_abc123"
// Session 2: User logs in - MUST call identify()
await kitbase.identify({
userId: 'user-456',
traits: { email: 'user@example.com' },
});
// → Links anon_abc123 to user-456
// Subsequent events use user_id
await kitbase.track({
channel: 'purchases',
event: 'Purchase',
user_id: 'user-456',
});
// → All events now attributed to user-456Identity Linking Requires identify()
Kitbase does not automatically link anonymous users to identified users. You must explicitly call identify() after authentication.
User ID Management
// Get current user ID (set via identify)
const userId = kitbase.getUserId();
// => "user-123" or null
// Get anonymous ID
const anonymousId = kitbase.getAnonymousId();
// => "550e8400-e29b-41d4-a716-446655440000"
// Reset user data (clears user_id and generates new anonymous_id)
kitbase.reset();Best Practices
When to Call identify()
Call identify() immediately after:
- User login
- User signup
- User authentication via OAuth/SSO
// After successful login
async function handleLogin(credentials) {
const user = await authService.login(credentials);
// Identify the user immediately
await kitbase.identify({
userId: user.id,
traits: {
email: user.email,
name: user.name,
plan: user.subscription?.plan,
},
});
// Track the login event
await kitbase.track({
channel: 'users',
event: 'User Logged In',
user_id: user.id,
icon: '🔐',
});
}Consistent User IDs
Use the same user_id format across your application:
// Good: Consistent format
user_id: user.id // Database ID
user_id: user.email // Email (if unique)
user_id: user.uuid // UUID
// Bad: Inconsistent formats
user_id: user.id // "123" in one place
user_id: user.email // "user@example.com" in anotherUpdate Traits on Profile Changes
Call identify() again when user properties change:
async function handleProfileUpdate(updates) {
await userService.update(updates);
// Update traits
await kitbase.identify({
userId: currentUser.id,
traits: {
name: updates.name || currentUser.name,
plan: updates.plan || currentUser.plan,
},
});
}Multi-Device Users
When a user logs in on a new device:
- The new device has its own anonymous ID
- Calling
identify()links both devices to the same user - Events from both devices are attributed to the same user
// Device A: anonymous_id = "aaa-111"
// Device B: anonymous_id = "bbb-222"
// User logs in on Device A
await kitbase.identify({ userId: 'user-123' });
// → aaa-111 linked to user-123
// User logs in on Device B
await kitbase.identify({ userId: 'user-123' });
// → bbb-222 also linked to user-123
// Both devices' events are now attributed to user-123MAU Accuracy
Identity resolution prevents double-counting users who browse anonymously before signing in. A user who visits your site anonymously and later creates an account counts as one MAU, not two.