Identify signed-in users

Sessions are anonymous (visitor a8f2k…) until your app says who is signed in. One call attaches the user to the whole visit — even retroactively within the session — and makes sessions searchable by person. This requires your own login system; static sites can skip it.

The call

// after your login succeeds:
logcohort('identify', {
  userId: user.id,     // required — your stable id for this user
  email: user.email,   // optional
  name:  user.name,    // optional
});

Call it any time after your login succeeds. The command queue buffers it until the recorder has loaded, so there is no race with the script tag — you can never call it "too early".

Next.js (App Router)

When the user is known on the server (a session cookie), the clean pattern is: pass the user down as props from a server component, and call the queue in a tiny client component. No string-building, no escaping — React passes the values:

// app/logcohort-identify.tsx
"use client";

import { useEffect } from "react";

export function LogcohortIdentify({ userId, email, name }: {
  userId: string;
  email?: string | null;
  name?: string | null;
}) {
  useEffect(() => {
    window.logcohort?.("identify", { userId, email, name });
  }, [userId, email, name]);

  return null;
}
// app/layout.tsx — pass the server session down as props:
const session = await getServerSession();

<body>
  {children}
  {session?.user && (
    <LogcohortIdentify
      userId={session.user.id}
      email={session.user.email}
      name={session.user.name}
    />
  )}
</body>

This is race-free by construction: the loader stub in your layout runs during HTML parse, so window.logcohort exists before any effect fires, and the queue holds the identify until the recorder is ready. It's the exact pattern the logcohort dashboard uses to record itself.

One person across sites

Identify is also what joins a person across separate domains: when two of your sites identify the same userId, Journeys shows their sessions as one story — no setup beyond the call above. Keep each site its own project; sharing one key between sites to "merge" them mixes their metrics, while identify does the joining without that cost.

What gets stored: only what you pass — an id, and optionally email and name. Identify never reads anything from the page on its own.