Identifying users
Your app already knows who is signed in. Tell Cluebase, and the conversation stops being with a stranger.
Coding Agent Prompt for Identity
Copy & paste this prompt into Cursor, Claude, ChatGPT, Copilot, or Antigravity to wire your existing auth into Cluebase.
Tell Cluebase who the signed-in user is, so the rescue agent greets them by name and never has to ask for an email:
1. Find how this project knows who is signed in (Clerk's `useUser()`, NextAuth's `useSession()`, Supabase auth, a custom context, whatever it already uses).
2. Pass it to `CluebaseProvider` at the application root:
`<CluebaseProvider apiKey={...} user={user ? { id: user.id, email: user.email, name: user.name } : null}>`
Pass `null` when nobody is signed in. Only `id` is required; `email` and `name` are optional, and `metadata` accepts a flat object of string/number/boolean values.
3. If auth resolves after mount, use the hook instead of the prop:
`const { identify, reset } = useCluebaseIdentify();`
Call `identify({ id, email, name })` once the user is known.
4. Call `reset()` on logout. Without it the previous user stays attached to reports for the life of the page, so on a shared machine the next person's error is reported as them.
5. Do not add identity to logged-out pages, marketing pages, or guest checkout. Those are fully supported without it: the agent simply asks for contact details in conversation, which is the existing behaviour.
RULES, these matter more than the wiring:
- Pass ONLY what the app already knows. Never read localStorage, sessionStorage, cookies, or any token to find out who someone is. Never decode a JWT. Never scan the DOM or read form field values. Cluebase never infers identity and neither should this integration.
- Never derive a name from an email address. "j.smith@corp.com" is not "J Smith". If there is no name, pass none: the agent handles that and simply skips the greeting.
- Do not invent a `metadata` payload. Add fields only if the person asks for them, and keep it flat: nested objects are dropped.
Note: If you have web search capability, visit https://cluebase.dev/docs/identity for detailed documentation.By default the agent has to ask the person who they are, because it has no way of knowing. That is a reasonable question to ask a logged-out visitor and a strange one to ask somebody who signed in ten minutes ago. When you supply the user, the agent opens by name, goes straight to what they were trying to do, and never asks for an email address. The incident arrives on your dashboard with a real person on it instead of "Unknown visitor".
The quickest version
Pass a user object to the provider. Pass null when nobody is signed in.
<CluebaseProvider apiKey={process.env.NEXT_PUBLIC_CLUEBASE_API_KEY!} user={user ? { id: user.id, email: user.email, name: user.name } : null}> {children}</CluebaseProvider>Only id is required. It is your own identifier for that person and is never shown to them. email and name are both optional.
type CluebaseUser = { id: string // required if user is supplied at all email?: string name?: string metadata?: Record<string, string | number | boolean>}With Clerk
'use client'
import { useUser } from '@clerk/nextjs'import { CluebaseProvider } from 'cluebase-next'
export function Providers({ children }) { const { user } = useUser()
return ( <CluebaseProvider apiKey={process.env.NEXT_PUBLIC_CLUEBASE_API_KEY!} user={user ? { id: user.id, email: user.primaryEmailAddress?.emailAddress, name: user.fullName ?? undefined, } : null} > {children} </CluebaseProvider> )}With NextAuth
'use client'
import { useSession } from 'next-auth/react'import { CluebaseProvider } from 'cluebase-next'
export function Providers({ children }) { const { data: session } = useSession()
return ( <CluebaseProvider apiKey={process.env.NEXT_PUBLIC_CLUEBASE_API_KEY!} user={session?.user ? { id: session.user.id, email: session.user.email ?? undefined, name: session.user.name ?? undefined, } : null} > {children} </CluebaseProvider> )}When auth resolves after mount
Some apps do not know who the user is at the moment the provider renders. Use the hook instead, and call it once you do know.
import { useCluebaseIdentify } from 'cluebase-next'
function AfterLogin({ user }) { const { identify } = useCluebaseIdentify()
useEffect(() => { if (user) identify({ id: user.id, email: user.email, name: user.name }) }, [user])}The prop and the hook write to the same place, so pick whichever suits the call site. If you use both, the most recent call wins, and the SDK warns you in development that two sources are in play.
Clearing identity on logout
Call reset() when someone signs out.
const { reset } = useCluebaseIdentify()
async function handleLogout() { await signOut() reset()}reset(), the previous user stays attached for the life of the page. The next person to hit an error is reported as whoever logged out last. If you pass user as a prop and set it to null on logout, that is already handled and you do not need to call reset() as well.Extra context with metadata
A flat set of key/value pairs, shown alongside the incident. Useful for the thing your team will immediately want to know.
user={{ id: user.id, email: user.email, name: user.name, metadata: { plan: 'pro', seats: 12, trialing: false },}}Values must be a string, number, or boolean. Nested objects and arrays are rejected by the type and dropped at runtime, with a warning in development. That limit is deliberate: it stops an entire user record, tokens included, being posted through a field meant for a few flags.
Users you cannot identify
Leaving user out is not a degraded mode, and you should expect to be in it often. Logged-out pages, sign-up and password-reset flows, guest checkout, marketing pages, and crashes that happen during hydration before your auth has resolved all arrive without identity. Some of those are the most valuable errors you will ever catch.
In those cases the agent behaves exactly as it always has: it asks what happened, and asks for contact details conversationally once it has been useful. Both paths are first-class.
Turning identity off entirely
<CluebaseProvider apiKey={...} identity={false} />With this set, the user prop is ignored, identify() becomes a no-op, and nothing about your end users is transmitted, even if you call it. Errors are still captured and your team is still alerted; only the "who" is withheld. The drop happens in the browser before anything reaches the network, so it is something a reviewer can verify in the SDK source rather than a promise about what our servers do.
What Cluebase will never do
user prop or identify(), and through nothing else. If neither is called, every incident is anonymous.Names are used exactly as you give them and are never derived from an email address. If you supply an email but no name, the agent skips the greeting rather than guessing at one.
Deleting a user's data
Because every incident carries the id you supplied, you can erase everything held about one person on request. Open any of their incidents in the dashboard and use Delete user data: it removes every conversation and all contact details across all of their incidents, not just the one on screen.
Next steps
- Configuration: the full props reference
- Manual reporting: for caught errors and async calls
