Skip to main content

What is user identification?

By default, every event tracked by Analytiq is anonymous — you can see that a button was clicked, but not who clicked it. identify() links all future events to a specific user. After you call it, every track() event is automatically tagged with that user’s ID — so on the dashboard you can filter events by user, see a single user’s journey, and understand your users individually.

When to call identify()

Call identify() in exactly one place: right after login or signup succeeds.
User clicks Login button
  - Your API call succeeds
  - Call identify(user) here
  - User is redirected to dashboard

Basic usage

import { identify } from 'analytiq'

// Pass any unique ID — usually user.id from your database
identify('user_abc123')
You can use:
  • A database UUID or integer ID: identify('550e8400-e29b-41d4-a716-446655440000')
  • An email address: identify('john@example.com') (only if emails are unique)
  • Any unique string your system uses

After signup

If you used the analytics.jsx “One-File Setup” from the Quickstart, you don’t need to call identify manually.When your user signs up successfully, your app’s authentication state changes. The useEffect inside your analytics.jsx file detects the new user and calls identify() for you automatically.
components/Signup.jsx
import { track } from '../analytics.jsx'    // Import from your hub, not the package!

async function handleSignup(email, password) {
  try {
    const response = await api.post('/auth/register', { email, password })
    
    // 1. Update your app's user state (triggers your analytics.jsx hook)
    setUser(response.data.user)

    // 2. Track the signup event manually
    track('signup_completed', { method: 'email' })
    navigate('/dashboard')

  } catch (error) {
    track('signup_failed', { reason: error.message })
  }
}

After login

Just like signup, you don’t need to call identify manually.When the login succeeds and you update your user state, the useEffect in your analytics.jsx file automatically fires identify().
components/Login.jsx
import { track } from '../analytics.jsx'

async function handleLogin(email, password) {
  const response = await api.post('/auth/login', { email, password })

  // Just update your auth state — your analytics.jsx handles identify!
  setUser(response.data.user)
  track('login_success')
  navigate('/dashboard')
}

When the user is already logged in (page refresh)

If your app keeps users logged in, you need to re-identify them when the app loads after a page refresh — otherwise events after a refresh won’t be linked to their identity.
This is handled automatically. When your app loads, your useAuth hook automatically fetches the user from local storage or cookies. Because that variable updates, the useEffect inside analytics.jsx runs again and successfully calls identify() automatically.

Resetting on logout

When a user logs out, their identity must be cleared so the next person using the device doesn’t inherit it.
This is handled automatically. When you clear your user state, your auth hook becomes empty. The useEffect inside analytics.jsx detects this and automatically calls reset().You do not need to call reset() manually inside your Logout button if you have the analytics.jsx file installed perfectly.

How identity flows through events

After identify() is called, all subsequent track() calls are automatically linked:
identify('user_abc')
track('page_view', { page: 'Dashboard' })     // linked to user_abc
track('upgrade_clicked', { plan: 'pro' })     // linked to user_abc
track('purchase', { amount: 49 })             // linked to user_abc
reset()
track('page_view', { page: 'Landing' })       // anonymous again

What NOT to do

Don’tWhy
identify(user.email) if emails can changeUser gets new email, resulting in their history being split
identify(user.name)Names aren’t always unique
Call identify() before login succeedsYou might identify the wrong user
Skip reset() on logoutNext user inherits previous user’s identity

Anonymous events before identify()

Any events tracked before identify() is called are stored anonymously. Once you call identify(), future events are linked — but past anonymous events remain anonymous. This is expected behavior.

Tracking anonymous visitors (no login required)

If your app or website has users who never log in (a marketing landing page, a blog, a documentation site), identify() is never called naturally — and all events will have userId = null, meaning they won’t appear in your Unique Users, DAU, or MAU counts. The fix is to generate a stable visitor ID using localStorage. This creates a unique ID the first time someone visits, stores it in their browser, and reuses it on every future visit — all without requiring any login.
Add this to your analytics.jsx provider file, before or alongside the useAuth identify logic:
src/analytics.jsx
import { Analytiq, identify, reset, track } from 'analytiq/react'
import { useEffect } from 'react'
import { useAuth } from './context/AuthContext'

// Generate a stable anonymous visitor ID
function getVisitorId() {
  let id = localStorage.getItem('_visitor_id')
  if (!id) {
    id = crypto.randomUUID()
    localStorage.setItem('_visitor_id', id)
  }
  return id
}

export function AnalyticsProvider({ children }) {
  const { user } = useAuth()

  useEffect(() => {
    if (user) {
      identify(user)          // Logged-in user: use their real identity
    } else {
      identify(getVisitorId()) // Anonymous visitor: use stable browser ID
    }
  }, [user])

  return (
    <>
      <Analytiq apiKey={import.meta.env.VITE_ANALYTIQ_KEY} />
      {children}
    </>
  )
}

export { track }
How this works: crypto.randomUUID() generates a unique ID (like "f47ac10b-58cc-4372-a567-0e02b2c3d479") the very first time someone visits. It is saved in localStorage so future visits by the same person reuse the same ID — giving you accurate repeat visitor counts.
This visitor ID is device and browser specific. If the same person visits from Chrome and Safari, they will appear as two different visitors. This is expected for anonymous tracking — it is the same behavior used by most analytics platforms for unauthenticated users.
ScenarioWhat happens
First visit, no loginNew visitor ID generated → DAU and Unique Users count this visitor
Return visit, no loginSame visitor ID reused → recognized as the same visitor
User logs in after browsingidentify(user) overrides the visitor ID → events now linked to their real account
User logs outBack to visitor ID → browsing continues tracked anonymously