useIdentify
The declarative identify hook. Calls identify() whenever the user ID changes. No manual useEffect wiring.
Import
import { useIdentify } from "@galacha/react";Basic usage
function AppShell() {
const { user } = useAuth();
useIdentify(user?.id, {
email: user?.email,
name: user?.name,
plan: user?.plan,
});
return <Routes />;
}Re-runs whenever userId changes. Safe to call with null/undefined when the user isn't logged in — it becomes a no-op.
Signature
function useIdentify(
userId: string | null | undefined,
traits?: GalachaTraits,
): void;What happens under the hood
On every render:
- Hook compares the current
userIdagainst the previous one - If
userIdis falsy, nothing happens - If
userIdchanged, callsidentify(userId, traits)on the Galacha context - Traits object is compared by its JSON serialization, so object identity doesn't matter — only the contents
Common patterns
Simple auth context
import { useAuth } from "./auth";
import { useIdentify } from "@galacha/react";
function Root() {
const { user } = useAuth();
useIdentify(user?.id, {
email: user?.email,
name: user?.name,
});
return <App />;
}Multi-tenant: include team/org
useIdentify(user?.id, {
email: user?.email,
team_id: user?.team_id,
team_name: user?.team_name,
role: user?.role,
});The dashboard lets you filter by trait, so sending team_id means you can pull up "all sessions from team_042".
SaaS with plan tier
useIdentify(user?.id, {
email: user?.email,
plan: user?.plan, // "free" | "pro" | "enterprise"
seats: user?.seat_count,
mrr: user?.monthly_revenue,
});Filter the dashboard by plan:pro to watch only paying users. Sort by mrr to triage by value.
Updating traits after a plan change
const [user, setUser] = useState(initialUser);
// When the user upgrades
const handleUpgrade = async () => {
const updated = await api.upgradeToPro();
setUser(updated); // useIdentify re-runs automatically with new traits
};Because useIdentify re-runs on trait changes, you don't need a manual identify() call after the upgrade.
Server-authenticated SSR
If you read the user from a cookie during SSR and pass it down:
// Server: pages/dashboard.tsx
export async function getServerSideProps({ req }) {
const user = await getUserFromSession(req);
return { props: { user } };
}
// Client: same file
function Dashboard({ user }) {
useIdentify(user.id, { email: user.email });
return <div>...</div>;
}The identify fires on first client render, before the user does anything.
Why not just call identify() in a useEffect?
You can. useIdentify is a thin convenience:
// Manual
const { identify } = useGalacha();
useEffect(() => {
if (user?.id) identify(user.id, { email: user.email });
}, [user?.id]);
// With useIdentify
useIdentify(user?.id, { email: user?.email });Same result, less boilerplate, correctly handles the ready + traits change cases.
Not for multi-user switching
If your app lets users switch accounts within a single session (uncommon), prefer the imperative identify() from useGalacha(). useIdentify only fires on userId change, which is usually what you want, but the imperative version gives you explicit control.