User Identification

Identify and track users across sessions with persistent user IDs and properties

Human Behavior automatically identifies and tracks users across sessions using persistent user IDs and properties.

Automatic User Identification

The SDK handles user identification using cookies. A unique endUserId (UUID) is generated and stored in a cookie on first visit, and persists for 365 days. Initializing the SDK handles this automatically — you don't need to call anything to start tracking an anonymous user.

Once you call identifyUser, the anonymous user is merged into the identified user, and future sessions on the same browser resolve to the canonical user.

User Identification Methods

Call this once per session, as soon as you know who the user is (after login/signup, on page load for authenticated users, etc.).

const endUserId = await tracker.identifyUser({
  userId: user.id,              // your internal/external user ID (optional but recommended)
  userProperties: {
    email: user.email,
    name: user.name,
    plan: user.plan
  }
});

console.log('User identified with ID:', endUserId);

Returns: Promise<string> - The endUserId (the anonymous UUID for the current session).

The userId parameter

userId is your application's own ID for this user (e.g. the primary key in your users table, Firebase UID, Clerk ID). It is the primary merge key for identity resolution:

  • If Human Behavior has already seen this userId in your project, the current browser is reconciled to that canonical user — all prior sessions and events line up under the same identity.
  • If not, the anonymous user is promoted to hold this userId, so every future browser that identifies with the same userId resolves back to this user.

Pass it whenever you have it. Without userId, Human Behavior falls back to email-based matching if an email is provided in userProperties, and otherwise treats each browser as a separate user.

2. identifyUserGlobally() - Global Function

Use this when you don't have direct access to a tracker instance (e.g. from a utility module or auth callback that doesn't receive the tracker as a dependency).

import { identifyUserGlobally } from 'humanbehavior-js';

const endUserId = await identifyUserGlobally(
  {
    email: user.email,
    name: user.name,
    plan: user.plan
  },
  user.id  // optional userId (same meaning as above)
);

console.log('User identified globally with ID:', endUserId);

Signature: identifyUserGlobally(userProperties, userId?)

Returns: Promise<string> | null - The endUserId if successful, null if no tracker has been initialized yet.

Updating user properties later

You don't have to call identifyUser again to update properties. Use the property helpers:

// Single property
tracker.setUserProperty('plan', 'enterprise');

// Multiple properties at once
tracker.setUserProperties({
  plan: 'enterprise',
  seats: 25,
  annualContract: true
});

// Set only if it hasn't been set before (e.g. acquisition attribution)
tracker.setOnce('first_campaign', 'spring_launch', 'user');

// Remove or clear
tracker.removeUserProperty('trialEndsAt');
tracker.clearUserProperties();

These attach to every future event for the user, and persist across sessions on the same browser.

User Logout

When a user signs out, call tracker.logout(). This clears the endUserId cookie, rotates the session, and starts recording a fresh anonymous user — so the next sign-in on the same browser doesn't get merged into the previous account.

const handleLogout = async () => {
  await signOutFromYourAuthProvider();
  tracker.logout();
  // redirect, clear local state, etc.
};

Omitting logout() means a shared computer (library kiosk, shared laptop, etc.) will attribute the next user's session to the previous account until they call identifyUser themselves.

Framework-Specific Examples

NextAuth.js Example

// In your NextAuth configuration
import { HumanBehaviorTracker } from 'humanbehavior-js';

export default NextAuth({
  events: {
    async signIn({ user, account }) {
      const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);

      await tracker.identifyUser({
        userId: user.id,
        userProperties: {
          email: user.email,
          name: user.name,
          provider: account?.provider
        }
      });
    },
    async signOut() {
      const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);
      tracker.logout();
    }
  }
});

Firebase Auth Example

import { HumanBehaviorTracker } from 'humanbehavior-js';

onAuthStateChanged(auth, async (user) => {
  const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);

  if (user) {
    await tracker.identifyUser({
      userId: user.uid,
      userProperties: {
        email: user.email,
        name: user.displayName,
        image: user.photoURL,
        provider: user.providerData[0]?.providerId
      }
    });
  } else {
    tracker.logout();
  }
});

Google Auth Example

import { HumanBehaviorTracker } from 'humanbehavior-js';

const handleGoogleSignIn = async () => {
  const user = await signInWithGoogle();
  if (!user) return;

  const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);
  await tracker.identifyUser({
    userId: user.uid,
    userProperties: {
      email: user.email,
      name: user.displayName,
      image: user.photoURL,
      provider: 'google'
    }
  });
};

Client-side Identification

Placement: Call identifyUser after successful login, signup, or on page load for already-authenticated users. Don't call it during initial page render before you know who the user is — it will just identify anonymous traffic.

Inspecting the current user

tracker.getUserInfo();
// → { endUserId: string | null, sessionId: string, isPreexistingUser: boolean, initialized: boolean }

tracker.getUserAttributes();
// → { ...properties passed to identifyUser }

tracker.isPreexistingUser();
// → true if this browser has an endUserId cookie from a previous session

Useful for gating logic like "only fire onboarding for first-time visitors."

Complete Example

AuthComponents.jsx
import { HumanBehaviorTracker } from 'humanbehavior-js';

function LoginForm() {
    const handleLogin = async (formData) => {
      // ... your authentication logic ...

      if (loginSuccessful) {
        const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);

        await tracker.identifyUser({
          userId: user.id,
          userProperties: {
            email: user.email,
            name: user.name,
            plan: 'premium'
          }
        });
      }
    }

    return (
        <form onSubmit={handleLogin}>
            {/* Your form fields */}
        </form>
    );
}

function LogOutButton() {
  const handleLogout = async () => {
    const tracker = HumanBehaviorTracker.init(process.env.NEXT_PUBLIC_HUMAN_BEHAVIOR_API_KEY);
    // ... your sign-out logic ...
    tracker.logout();
  }

  return (
    <button onClick={handleLogout}>Log Out</button>
  );
}

Privacy & Segmentation

  • User properties are available in your analytics dashboard for segmentation and filtering
  • You can update user info at any time (e.g., after signup, plan change) with setUserProperty / setUserProperties
  • The SDK supports privacy regulations and pseudonymous IDs

Properties & Options

Property/OptionTypeDescription
endUserIdstringUnique user ID (auto-generated and stored in a cookie by default).
userIdstringYour application's user ID. Primary merge key for identity resolution.
userPropertiesobjectAny key-value pairs (e.g., email, name, plan, etc.).
cookiestringhuman_behavior_end_user_id, stored for 365 days.

identifyUser({ userProperties, userId }) fields:

FieldTypeDescription
userIdstringOptional. Your internal/external user ID (primary merge key).
userProperties.emailstringUser's email address (used for fallback matching if userId is absent).
userProperties.namestringUser's name.
userProperties.*anyAny additional properties you want to attach to the user.

Method Comparison

MethodWhen to UseReturns
tracker.identifyUser({ userProperties, userId })You have tracker instancePromise<string>
identifyUserGlobally(userProperties, userId?)No tracker access, global usagePromise<string> | null
tracker.setUserProperty(k, v) / setUserProperties(obj)Update user properties after identificationvoid
tracker.logout()User signed out — clear identity and rotate sessionvoid
tracker.getUserInfo()Inspect current identity stateobject
tracker.isPreexistingUser()Check if this browser has a returning user cookieboolean