tessl install tessl/npm-posthog-js@1.335.0PostHog Browser JS Library is a comprehensive browser analytics and feature management SDK that enables developers to capture user events, track product analytics, manage feature flags, record session replays, and implement feedback mechanisms like surveys and conversations in web applications.
User identification allows you to associate events with specific users, set person properties, create aliases between distinct IDs, and manage user state.
Identifies a user with a distinct ID and optionally sets person properties.
/**
* Identifies a user with a distinct ID and sets person properties
* @param new_distinct_id - Unique identifier for the user (optional)
* @param userPropertiesToSet - Properties to set on the person profile
* @param userPropertiesToSetOnce - Properties to set only if not already set
*/
function identify(
new_distinct_id?: string,
userPropertiesToSet?: Properties,
userPropertiesToSetOnce?: Properties
): void;Usage Examples:
// Identify with just a user ID
posthog.identify('user-123');
// Identify with user ID and properties
posthog.identify('user-123', {
email: 'user@example.com',
name: 'John Doe',
plan: 'premium'
});
// Set properties only once (useful for immutable attributes)
posthog.identify('user-123',
{ last_login: new Date().toISOString() },
{ first_seen: new Date().toISOString() }
);
// Update properties without changing distinct ID
posthog.identify(undefined, {
subscription_status: 'active'
});Sets person properties without changing the distinct ID.
/**
* Sets person properties for the current user
* @param userPropertiesToSet - Properties to set on the person profile
* @param userPropertiesToSetOnce - Properties to set only if not already set
*/
function setPersonProperties(
userPropertiesToSet?: Properties,
userPropertiesToSetOnce?: Properties
): void;Usage Example:
// Update user properties
posthog.setPersonProperties({
subscription_tier: 'pro',
last_active: new Date().toISOString()
});
// Set properties once (won't overwrite if already exists)
posthog.setPersonProperties(
{ current_plan: 'enterprise' },
{ signup_date: '2024-01-15' }
);Explicitly creates a person profile for the current user.
/**
* Explicitly creates a person profile for the current user
* Useful when person_profiles config is set to 'identified_only' or 'never'
*/
function createPersonProfile(): void;Usage Example:
// Force creation of person profile
posthog.createPersonProfile();Resets the user state, creating a new anonymous user.
/**
* Resets the user state, creating a new anonymous user
* @param reset_device_id - If true, also resets the device ID (default: false)
*/
function reset(reset_device_id?: boolean): void;Usage Examples:
// Reset user (keep device ID)
posthog.reset();
// Reset user and device ID (complete reset)
posthog.reset(true);
// Common use case: user logout
function logout() {
posthog.reset();
// Clear session, redirect, etc.
}Creates an alias linking two distinct IDs, allowing you to merge user profiles.
/**
* Creates an alias linking two distinct IDs
* @param alias - The new distinct ID to link
* @param original - The original distinct ID (optional, defaults to current distinct ID)
* @returns CaptureResult if successful
*/
function alias(alias: string, original?: string): CaptureResult | void | number;Usage Examples:
// Link anonymous user to identified user
const anonymousId = posthog.get_distinct_id();
posthog.alias('user-123'); // Links current ID to 'user-123'
// Explicit alias between two IDs
posthog.alias('user-123', 'anonymous-abc-def');
// Common pattern: after signup
function onSignup(userId) {
posthog.alias(userId);
posthog.identify(userId, {
email: user.email,
name: user.name
});
}Gets the current distinct ID for the user.
/**
* Gets the current distinct ID for the user
* @returns The current distinct ID
*/
function get_distinct_id(): string;Usage Example:
const distinctId = posthog.get_distinct_id();
console.log('Current user ID:', distinctId);
// Use in API calls
fetch('/api/user-data', {
headers: {
'X-User-ID': posthog.get_distinct_id()
}
});Gets all current group memberships for the user.
/**
* Gets all current group memberships
* @returns Object mapping group types to group keys
*/
function getGroups(): Record<string, any>;Usage Example:
const groups = posthog.getGroups();
console.log('User groups:', groups);
// Example output: { company: 'acme-inc', team: 'engineering' }Deprecated: Use setPersonProperties() instead.
/**
* @deprecated Use setPersonProperties() instead
* Sets person properties
* @param prop - Property name or properties object
* @param to - Property value (if prop is a string)
* @param callback - Optional callback for request completion
*/
function people.set(
prop: string | Properties,
to?: string,
callback?: RequestCallback
): void;Migration Example:
// Old way (deprecated)
posthog.people.set('email', 'user@example.com');
posthog.people.set({ name: 'John', age: 30 });
// New way
posthog.setPersonProperties({ email: 'user@example.com' });
posthog.setPersonProperties({ name: 'John', age: 30 });Deprecated: Use setPersonProperties() with second parameter instead.
/**
* @deprecated Use setPersonProperties(undefined, props) instead
* Sets person properties once if not already set
* @param prop - Property name or properties object
* @param to - Property value (if prop is a string)
* @param callback - Optional callback for request completion
*/
function people.set_once(
prop: string | Properties,
to?: string,
callback?: RequestCallback
): void;Migration Example:
// Old way (deprecated)
posthog.people.set_once('signup_date', '2024-01-15');
posthog.people.set_once({ initial_referrer: 'google' });
// New way
posthog.setPersonProperties(undefined, { signup_date: '2024-01-15' });
posthog.setPersonProperties(undefined, { initial_referrer: 'google' });/**
* Object containing user or event properties
*/
type Properties = Record<string, Property | Property[]>;/**
* A single property value
*/
type Property = string | number | boolean | null | undefined;/**
* Callback for request completion
*/
type RequestCallback = (response: RequestResponse) => void;/**
* Response from a PostHog request
*/
interface RequestResponse {
/**
* HTTP status code
*/
statusCode: number;
/**
* HTTP status text
*/
statusText?: string;
/**
* Response body
*/
body?: string;
}When to call identify():
// After user logs in
async function login(email, password) {
const user = await authenticateUser(email, password);
posthog.identify(user.id, {
email: user.email,
name: user.name,
plan: user.plan
});
}
// After user signs up
async function signup(userData) {
const user = await createUser(userData);
// Create alias from anonymous ID to user ID
posthog.alias(user.id);
// Identify with user properties
posthog.identify(user.id, {
email: user.email,
name: user.name
});
}
// On app initialization (for already logged-in users)
async function initializeApp() {
const user = await getCurrentUser();
if (user) {
posthog.identify(user.id, {
email: user.email,
plan: user.plan
});
}
}Always reset user state when users log out:
function logout() {
// Reset PostHog state
posthog.reset();
// Clear local storage/session
localStorage.clear();
// Redirect to login
window.location.href = '/login';
}Handle both anonymous and identified users appropriately:
// Check if user is identified
function isUserIdentified() {
const distinctId = posthog.get_distinct_id();
// Anonymous IDs are UUIDs, identified IDs are typically not
return !distinctId.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
}
// Use different logic based on user state
if (isUserIdentified()) {
// Show personalized content
} else {
// Show generic content
}Control when person profiles are created using the person_profiles config:
// Only create profiles for identified users (recommended)
posthog.init('token', {
person_profiles: 'identified_only' // Default
});
// Always create profiles (more data, higher costs)
posthog.init('token', {
person_profiles: 'always'
});
// Never create profiles (anonymous-only tracking)
posthog.init('token', {
person_profiles: 'never'
});
// Force profile creation when needed
if (shouldCreateProfile()) {
posthog.createPersonProfile();
}Use aliases carefully to merge user identities:
// ✅ Good: Alias before identify
function onSignup(userId) {
posthog.alias(userId); // Link anonymous ID to user ID
posthog.identify(userId, { email: user.email });
}
// ❌ Bad: Identify without alias (creates separate profiles)
function onSignup(userId) {
posthog.identify(userId, { email: user.email });
// Anonymous events won't be linked to this user
}
// ✅ Good: Merge external IDs
function linkExternalAccount(externalId) {
const currentId = posthog.get_distinct_id();
posthog.alias(externalId, currentId);
}Use consistent naming for person properties:
// ✅ Good: Snake case, descriptive names
posthog.identify('user-123', {
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe',
subscription_tier: 'premium',
account_created_at: '2024-01-15',
total_purchases: 5
});
// ❌ Bad: Inconsistent naming
posthog.identify('user-123', {
Email: 'user@example.com',
firstName: 'John',
LastName: 'Doe',
'subscription-tier': 'premium'
});// App initialization
async function initApp() {
const currentUser = await checkAuth();
if (currentUser) {
// Identify logged-in user
posthog.identify(currentUser.id, {
email: currentUser.email,
plan: currentUser.plan
});
}
// Otherwise, user remains anonymous
}
// Signup flow
async function handleSignup(formData) {
const newUser = await createAccount(formData);
// Create alias to link anonymous activity
posthog.alias(newUser.id);
// Identify with initial properties
posthog.identify(newUser.id, {
email: newUser.email,
name: newUser.name
}, {
signup_date: new Date().toISOString(),
initial_referrer: document.referrer
});
}
// Login flow
async function handleLogin(credentials) {
const user = await authenticate(credentials);
// Identify returning user
posthog.identify(user.id, {
email: user.email,
last_login: new Date().toISOString()
});
}
// Logout flow
function handleLogout() {
posthog.reset();
clearSession();
redirectToLogin();
}Update user properties as you learn more:
// On signup: basic info
posthog.identify(userId, {
email: user.email,
name: user.name
});
// After onboarding: preferences
posthog.setPersonProperties({
preferred_language: 'en',
notification_settings: 'daily'
});
// After first purchase: lifecycle stage
posthog.setPersonProperties({
customer_stage: 'active',
first_purchase_date: new Date().toISOString()
});
// Properties set once (never updated)
posthog.setPersonProperties(undefined, {
signup_referrer: document.referrer,
initial_utm_source: utmSource
});