Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.trodo.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Trodo assigns an anonymous id to every browser session. When you learn who a user is (after login or signup), call identify() to link their anonymous activity to a stable identifier.
Browser vs. server. The browser SDK is the only environment where identify changes persisted state — it rewrites the stored distinct id and merges the anonymous profile with the identified one. On the server, “identify” just records an identity link; you still pass distinctId on every subsequent call.

Signatures

Trodo.identify(identifyId)
Trodo.reset()
identifyId / identify_id
string
required
Stable identifier for the user — database id, account uuid, Stripe customer id. Max 255 chars.

Basic usage

// After login
Trodo.identify('user-42');

// Optionally set traits in the same flow
Trodo.people.set({ email: user.email, plan: user.plan });

Browser: when to call identify

1

After login

async function handleLogin(email, password) {
  const user = await login(email, password);
  Trodo.identify(user.id);
  Trodo.people.set({ email: user.email, plan: user.plan });
}
2

After signup

Identify immediately so the signup event is attributed to the new identified profile — then set set_once properties like signup date.
async function handleSignup(form) {
  const user = await createUser(form);
  Trodo.identify(user.id);
  Trodo.people.set_once({ signupDate: new Date().toISOString() });
  Trodo.track('signup_completed', { source: form.referralSource });
}
3

On app init for returning users

await Trodo.init({ siteId: 'your-site-id' });
const current = getCurrentUser();
if (current) Trodo.identify(current.id);

Server: “identify” is just a server write

On the backend there is no session to merge — every call already passes a distinct id. What trodo.identify(id) / trodo.identify(id) does on the server is hit POST /api/sdk/identify, letting the backend merge engine link the distinct id to an application identity. The returned UserContext is a convenience — you can keep using trodo.forUser('user-42') instead.
// You'll typically call identify once per login, in your auth handler
app.post('/auth/login', async (req, res) => {
  const user = await authenticate(req.body);

  await trodo.identify(user.id);               // records the link
  await trodo.track(user.id, 'login_completed'); // distinct id still required
});

Reset

Clear identity and start a new anonymous session. Always call on logout.
function handleLogout() {
  Trodo.track('logout_completed');
  Trodo.reset();                 // clears the stored distinct id
  logoutFromApp();
}
Browser: always reset() on logout. Without it, the next user on the same device inherits the previous user’s distinct id.

Identity merge behaviour

When identify() runs, the Trodo backend:
  1. New id → converts the anonymous profile into an identified profile for that id.
  2. Existing id, same device → seamless merge.
  3. Existing id, new device → the server’s merge engine unifies the profiles and may return a newDistinctId. The SDK updates its session map.
  4. Group memberships → for browser users, the server returns the user’s existing group memberships and the SDK hydrates local state so Groups assignments stay consistent across devices.

Best practices

Use persistent ids

✅  user.id            (stable database id)
✅  user.uuid          (stable uuid)
❌  user.username      (user can change it)
❌  user.displayName   (not unique)

Don’t over-identify

Call identify once per login — not on every click. The browser SDK remembers the id; re-identifying is wasted work.

Handle auth state changes

auth.onAuthStateChanged((user) => {
  if (user) Trodo.identify(user.uid);
  else Trodo.reset();
});

User properties

Set persistent traits

Groups

Associate users with orgs and teams