Skip to content

Conversation

@rockwellll
Copy link
Collaborator

@rockwellll rockwellll commented Dec 31, 2025

The Issue

Currently, associating a user with a session is a manual and repetitive process. Developers must pass identity_parameters into every single track call. This architecture leads to several problems:

  • Inconsistency: If a developer misses the identity parameters on a specific event, that event is lost to anonymity, even if the user is logged in.

  • Payload Bloat: Repetitive identity data is passed through the params object, cluttering the domain logic of the event (e.g., product or cart data).

  • Integration Friction: Platforms like Fenicio, which lack automatic post-login events, require a standard way to "bind" a session to a user profile upon login.

The Change

This PR introduces a Persistent Identity Layer to the SDK. By centralizing the user state, the SDK now "remembers" who the user is across page loads and automatically attaches that identity to all outgoing tracking events.

Key Components:

  1. User Model: A new internal model that manages the lifecycle of the user's identity. It uses browser cookies (hello_user_id and hello_user_source) to ensure the identity persists throughout the browser session.
  2. Hellotext.identify(id, options): A new top-level method to explicitly set the user's identity. It performs an async call to the new public/identifications endpoint and, upon success, persists the ID locally.
  3. Automatic Stitching in track: The track method has been refactored to automatically inject the persisted user data into the request body under a nested user key.
  4. Hellotext.forget(): A cleanup method to clear the identity cookies, essential for handling user logouts and preventing data cross-contamination on shared devices.

Presentation in Code

1. Centralized State (models/user.js)

The User class acts as the single source of truth for the current identity.

static get identificationData() {
  if (!this.id) return null;

  return {
    user_id: this.id,
    source: this.source,
  };
}

2. Clean Tracking Body (hellotext.js)

The track method now merges the global identity automatically, removing the need for manual identity_parameters in the event params.

const body = {
  session: this.session,
  action,
  user: User.identificationData, // Automatically injected
  ...params,
  ...pageInstance.trackingData,
};

3. Explicit Identification API

static async identify(externalId, options = {}) {
  const response = await API.identifications.create({
    user_id: externalId,
    ...options,
  });

  if (response.succeeded) {
    User.remember(externalId, options.source);
  }

  return response;
}

How to Use

Once the user logs in, call identify once:

Hellotext.identify('customer_123', { source: 'shopify', shop: 'store.com' });

All subsequent events will now be automatically attributed:

// No identity params needed here anymore!
Hellotext.track('product_viewed', { product_id: '456' });

Note

Persistent Identity Layer

  • Adds User model backed by cookies (hello_user_id, hello_user_source) and exposes Hellotext.identify(user_id, options) and Hellotext.forget()
  • Auto-injects user (from User.identificationData) into track request body
  • Implements public/identifications API client and wires it into API
  • Updates TypeScript defs: identify API, IdentificationOptions/Data, and User/Cookies types
  • New tests for identification flow and User model behavior
  • Documentation: moves/expands sessions and identity guidance to docs/sessions.md, adds README link
  • CI: bump actions/checkout and actions/setup-node to v6 and minor YAML quoting cleanup

Written by Cursor Bugbot for commit c112539. This will update automatically on new commits. Configure here.

@rockwellll rockwellll merged commit 9fcf3b9 into main Dec 31, 2025
3 checks passed
@rockwellll rockwellll deleted the identifications branch December 31, 2025 08:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants