Introduction
Usertour.js is a lightweight client-side SDK that enables you to:- Identify and track users in your web application
- Display interactive content (flows) to your users
- Collect user behavior data for targeting
Core Methods
Here are the most commonly used methods:Installation
Recommended: NPM Installation
We recommend using the npm package for the best development experience:If you’re using a self-hosted UserTour instance, you’ll need additional configuration to connect Usertour.js to your own server. See our Self-Hosted Usertour.js Guide for detailed setup instructions.
Quick Start
Add this code to your application where you have access to user information:Important Notes
Replace Placeholders
- Replace all placeholders (e.g.,
<USERTOUR_TOKEN>,<USER_ID>,<NAME>,<EMAIL>) with your actual values - The
signed_up_attimestamp should be in ISO 8601 format
Getting Your Token
- Find your Usertour.js Token in Settings -> Environments
- Each environment (Production, Staging, etc.) has its own unique token
- Make sure to use the correct token for your environment
How It Works
The npm package (usertour.js) is a thin wrapper around the real Usertour.js, which is loaded from our CDN. This design allows you to interact with the imported usertour object immediately. When you make your first method call, the real Usertour.js will be automatically loaded (asynchronously) and injected into the current page. All method calls are automatically queued by the usertour object until the SDK is ready.
The core SDK is optimized for performance:
- Small footprint (less than 16 KB gzipped)
- Loads UI components only when needed
- Supports both modern and legacy browsers
<script> tag, you can access the object via window.usertour. However, be aware that it may not be immediately available, which is why we recommend using the npm package.
Attributes
The SDK provides a flexible attribute system for storing data about various entities like users, companies, and events. You can use this to store a user’s name, a company’s plan type, or decorate events with information like which billing plan was selected. These attributes can then be used within Usertour to segment users, personalize flows, or track behavior. When updating objects with attributes, you can use various data types:
Here’s how to use attributes in your code:
Date object is sent as an ISO 8601 UTC timestamp, so signed_up_at: new Date(user.createdAt) is the simplest way to store a datetime.
Attribute types
Every attribute has a definition with a type. The first value you send for a new attribute creates the definition and decides its type — a string is stored as datetime only in the strict2024-12-12T00:00:00.000Z form (what Date.prototype.toISOString() produces), otherwise as string. Once a definition exists, later values must fit its type; conversions that lose nothing are applied for you, anything else is dropped (the SDK logs a warning) or rejected (the REST API returns 400):
You can change a definition’s type later in Settings → Attributes, as long as no stored value conflicts with the new type.
Random A/B and Random number
These two types are assigned by Usertour rather than written by you. Create one in Settings → Attributes (or through the REST API) on users or companies: every user or company then carries a fixed value —"A" or "B" split evenly, or a whole number from 1 to the upper bound you chose, spread evenly. The value is derived from the attribute and the user id, so it is the same on every device and never changes; users that existed before the attribute receive theirs in the background. Target one flow at experiment is A and its variant at experiment is B, or roll a feature out with rollout <= 10 and raise the number over time.
Sending a value for one of these attributes is refused: the key is dropped, the SDK logs a warning, and the call’s result names it (see below).
What a write reports back
identify, identifyAnonymous, updateUser, group and updateGroup resolve once the server has stored the attributes. The result lists the attributes the server refused — a value that does not fit the definition’s type, or a system-generated attribute — with the reason; every other attribute was written:
Operations
Instead of a literal, an attribute value can be an object with exactly one operation. Operations are computed on the server, so they work even though the browser never sees the stored value:add is not idempotent: if a request is retried after the server already applied it, the value is added twice. For exact counts, track an event instead — conditions can match on how many times an event occurred, optionally within a time window.
Pinning the type with data_type
When the first value of a new attribute could be misread — a string that happens to look like a date, a phone number sent as a number — pin the type with data_type next to set or set_once. The value is converted to that type:
data_type only decides the type when the attribute is first created. It never changes an existing definition: a data_type that disagrees with the definition is treated as a type mismatch. Change the type in Settings → Attributes instead.
Event attributes accept literals, Date objects and { set, data_type } only. The same values and operations work through the REST API and the MCP server.
For best results, we recommend:
- Using consistent naming conventions (lowercase with underscores)
- Choosing appropriate data types for each attribute
- Avoiding storage of sensitive information