Skip to main content
The umami.identify() function allows you to associate a unique identifier with a user, enabling you to track their journey across sessions and better understand user behavior.

Overview

User identification is useful for:
  • Tracking authenticated users across sessions
  • Associating events with specific user accounts
  • Understanding individual user journeys
  • Analyzing behavior by user segments
  • Building user-specific analytics
Umami remains privacy-focused even with user identification. You control what data is sent, and all data remains anonymous unless you explicitly provide identifying information.

Basic Usage

Identify a User

Call identify() with a unique user ID:
umami.identify('user-12345');
After identification, all subsequent events will be associated with this user ID.

Identify with Additional Data

Attach user properties along with the ID:
umami.identify('user-12345', {
  email: '[email protected]',
  plan: 'premium',
  signup_date: '2024-01-15',
  role: 'admin'
});

Function Signatures

The identify() function accepts multiple parameter combinations:
umami.identify(userId: string): Promise<string>
Example:
umami.identify('user-12345');

How It Works

From the tracker source code (index.js:201-214):
const identify = (id, data) => {
  if (typeof id === 'string') {
    identity = id;  // Store user ID
  }

  cache = '';  // Clear cache to ensure event is sent
  return send(
    {
      ...getPayload(),  // Include default properties
      data: typeof id === 'object' ? id : data,
    },
    'identify',  // Event type is 'identify' not 'event'
  );
};
Key behaviors:
  1. Sets Internal Identity: The user ID is stored in an internal identity variable
  2. Clears Cache: Ensures the identify event is sent immediately
  3. Sends Identify Event: Sends a special identify type event (not a regular event)
  4. Persists for Session: The identity is included in all subsequent events until page reload

Identity in Events

Once identified, the user ID is automatically included in all tracked events:
// From index.js:56-66
const getPayload = () => ({
  website,
  screen,
  language,
  title: document.title,
  hostname,
  url: currentUrl,
  referrer: currentRef,
  tag,
  id: identity ? identity : undefined,  // User ID included here
});

Common Use Cases

User Login

Identify users when they log in:
async function handleLogin(user) {
  // Identify the user
  await umami.identify(user.id, {
    email: user.email,
    username: user.username,
    plan: user.subscription.plan,
    signup_date: user.createdAt
  });
  
  // Track the login event
  umami.track('user-login', {
    method: 'email',
    timestamp: Date.now()
  });
}

User Signup

Identify new users during registration:
async function handleSignup(userData) {
  // Create the user account
  const user = await createUser(userData);
  
  // Identify the new user
  await umami.identify(user.id, {
    email: user.email,
    plan: user.plan,
    referral_source: getReferralSource(),
    signup_date: new Date().toISOString()
  });
  
  // Track the signup event
  umami.track('user-signup', {
    plan: user.plan,
    method: 'email'
  });
}

Update User Properties

Update user data as their information changes:
// When user upgrades their plan
async function handlePlanUpgrade(newPlan) {
  // Update user properties
  await umami.identify({
    plan: newPlan,
    upgrade_date: new Date().toISOString(),
    previous_plan: currentUser.plan
  });
  
  // Track the upgrade event
  umami.track('plan-upgrade', {
    from: currentUser.plan,
    to: newPlan
  });
}

User Logout

Track when users log out:
function handleLogout() {
  // Track the logout event (identity still present)
  umami.track('user-logout', {
    session_duration: getSessionDuration(),
    timestamp: Date.now()
  });
  
  // Note: Identity persists until page reload
  // Consider redirecting to clear the session
  window.location.href = '/login';
}
The user identity persists in memory until the page reloads. There’s no built-in way to “unidentify” a user within the same page session.

Framework Integration

Use useEffect to identify users:
import { useEffect } from 'react';
import { useAuth } from './auth';

function App() {
  const { user } = useAuth();
  
  useEffect(() => {
    if (user && window.umami) {
      umami.identify(user.id, {
        email: user.email,
        plan: user.plan,
        role: user.role
      });
    }
  }, [user]);
  
  return <div>App Content</div>;
}
With Auth Context:
import { createContext, useContext, useEffect } from 'react';

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    // When user state changes
    if (user) {
      window.umami?.identify(user.id, {
        email: user.email,
        plan: user.plan
      });
    }
  }, [user]);
  
  return (
    <AuthContext.Provider value={{ user, setUser }}>
      {children}
    </AuthContext.Provider>
  );
}

User Segmentation

Use identification to segment users and analyze behavior:
// Segment by plan type
umami.identify(user.id, {
  plan: user.plan,              // 'free', 'premium', 'enterprise'
  user_type: user.type,         // 'individual', 'business'
  account_age: user.accountAge, // Days since signup
  mau: user.monthlyActive       // Boolean
});

// Segment by usage patterns
umami.identify(user.id, {
  features_used: user.features.length,
  last_active: user.lastActive,
  power_user: user.isPowerUser,
  beta_tester: user.isBetaTester
});

// Segment by organization
umami.identify(user.id, {
  organization_id: user.org.id,
  organization_size: user.org.size,
  industry: user.org.industry,
  role: user.role
});

Privacy Considerations

Be mindful of privacy when identifying users. Only send data you need and that users have consented to share.

What to Track

umami.identify(user.id, {
  plan: 'premium',
  role: 'admin',
  signup_date: '2024-01-15',
  features_enabled: ['api', 'exports'],
  organization_size: 'medium'
});
Safe, non-personally-identifiable data includes:
  • User tier/plan
  • Role or permission level
  • Signup date
  • Feature flags
  • Organization info (non-specific)

Best Practices

1

Use anonymous IDs

Use database IDs or UUIDs instead of emails or usernames:
// Good
umami.identify('user-12345');
umami.identify('uuid-a1b2c3d4-e5f6-7890');

// Avoid
umami.identify('[email protected]');
umami.identify('johndoe');
2

Hash sensitive data

If you must include sensitive data, hash it first:
import { sha256 } from 'crypto';

umami.identify(user.id, {
  email_hash: sha256(user.email),
  org_hash: sha256(user.organizationName)
});
3

Respect opt-outs

Check user preferences before identifying:
if (user.analyticsConsent) {
  umami.identify(user.id, {
    plan: user.plan
  });
}
4

Document your tracking

Maintain clear documentation of what you track and why:
/**
 * Identifies user in analytics
 * Tracked data:
 * - plan: Subscription tier for feature usage analysis
 * - role: Permission level for access pattern analysis
 * - signup_date: Account age for cohort analysis
 */
umami.identify(user.id, {
  plan: user.plan,
  role: user.role,
  signup_date: user.signupDate
});

Complete Example

Here’s a complete implementation with authentication:
// analytics.js
export class Analytics {
  static identify(user) {
    if (!window.umami) return;
    
    // Only identify if user has consented
    if (!user.analyticsConsent) return;
    
    umami.identify(user.id, {
      // User attributes
      plan: user.subscription.plan,
      role: user.role,
      
      // Account metadata
      signup_date: user.createdAt,
      account_age_days: this.getAccountAge(user.createdAt),
      
      // Organization (if applicable)
      has_organization: !!user.organizationId,
      organization_size: user.organization?.size,
      
      // Feature flags
      beta_features: user.betaFeatures,
      
      // Usage metrics
      last_active: user.lastActive,
      total_events: user.eventCount
    });
  }
  
  static track(event, data) {
    if (!window.umami) return;
    return umami.track(event, data);
  }
  
  static getAccountAge(createdAt) {
    const now = Date.now();
    const created = new Date(createdAt).getTime();
    return Math.floor((now - created) / (1000 * 60 * 60 * 24));
  }
}

// auth.js
import { Analytics } from './analytics';

export async function login(credentials) {
  const user = await api.login(credentials);
  
  // Identify user in analytics
  Analytics.identify(user);
  
  // Track login event
  Analytics.track('user-login', {
    method: credentials.method
  });
  
  return user;
}

export function logout() {
  Analytics.track('user-logout');
  
  // Redirect to clear session and identity
  window.location.href = '/login';
}

Next Steps

Event Tracking

Learn how to track user events

Event Data

Understand event data structure and limits

Build docs developers (and LLMs) love