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
1. identifyUser() - Instance Method (Recommended)
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
userIdin 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 sameuserIdresolves 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 sessionUseful for gating logic like "only fire onboarding for first-time visitors."
Complete Example
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/Option | Type | Description |
|---|---|---|
endUserId | string | Unique user ID (auto-generated and stored in a cookie by default). |
userId | string | Your application's user ID. Primary merge key for identity resolution. |
userProperties | object | Any key-value pairs (e.g., email, name, plan, etc.). |
cookie | string | human_behavior_end_user_id, stored for 365 days. |
identifyUser({ userProperties, userId }) fields:
| Field | Type | Description |
|---|---|---|
userId | string | Optional. Your internal/external user ID (primary merge key). |
userProperties.email | string | User's email address (used for fallback matching if userId is absent). |
userProperties.name | string | User's name. |
userProperties.* | any | Any additional properties you want to attach to the user. |
Method Comparison
| Method | When to Use | Returns |
|---|---|---|
tracker.identifyUser({ userProperties, userId }) | You have tracker instance | Promise<string> |
identifyUserGlobally(userProperties, userId?) | No tracker access, global usage | Promise<string> | null |
tracker.setUserProperty(k, v) / setUserProperties(obj) | Update user properties after identification | void |
tracker.logout() | User signed out — clear identity and rotate session | void |
tracker.getUserInfo() | Inspect current identity state | object |
tracker.isPreexistingUser() | Check if this browser has a returning user cookie | boolean |