User tracking

User tracking enables you to identify users in your application, personalize their experiences, and gather detailed analytics about user behavior.

How it works

1

User identification

Provide user data to Pointer when users authenticate, including a unique user ID and optional profile information.

2

Event tracking

Automatically track user interactions and optionally record custom events for deeper insights.

3

Analytics collection

View detailed user analytics and behavior patterns in your Pointer dashboard.

Key benefits

User identification

Maintain consistent user identity across sessions for seamless experiences and accurate analytics.

Personalized experiences

Create customized content and guidance based on user data and behavior patterns.

Progress tracking

Monitor completion of onboarding flows, feature adoption, and user engagement over time.

Detailed analytics

Access comprehensive user insights and interaction data in your dashboard.

Setting up user tracking

Basic implementation

Provide user data to the PointerProvider when initializing:

import { PointerProvider } from 'pointer-sdk';

function App() {
  return (
    <PointerProvider 
      projectId={process.env.POINTER_PROJECT_ID!}
      userData={{
        userId: "user_123",           // Required
        name: "Jane Smith",           // Optional
        email: "jane@example.com",    // Optional
        avatarUrl: "/avatar.png",     // Optional
        customData: {                 // Optional
          plan: "premium",
          companyId: "company_456"
        }
      }}
    >
      {children}
    </PointerProvider>
  );
}

At minimum, you must provide a userId to identify the user. Additional fields are optional but recommended for better personalization and analytics.

Dynamic user management

For applications where user data changes during the session, use the useUser hook:

import { useUser } from 'pointer-sdk';

function AuthenticatedApp() {
  const { userData, setUserData, clearUserData } = useUser();
  
  // Set user data after login
  const handleLogin = (authState) => {
    setUserData({
      userId: authState.user.id,
      name: authState.user.name,
      email: authState.user.email,
      customData: {
        plan: authState.user.plan,
        teamId: authState.user.teamId
      }
    });
  };
  
  // Clear user data on logout
  const handleLogout = () => {
    clearUserData();
  };
  
  return (
    <div>
      <h1>Welcome, {userData?.name}</h1>
      <button onClick={handleLogout}>Logout</button>
    </div>
  );
}

User data structure

Required fields

userId
string
required

A stable, unique identifier for the user from your authentication system.

Optional fields

name
string

The user’s full name for personalization and display purposes.

email
string

The user’s email address for identification and communication.

avatarUrl
string

URL to the user’s profile picture or avatar image.

customData
object

Any additional JSON-serializable data you want to associate with the user.

Event tracking

Track custom events to understand how users interact with your application:

import { useUser } from 'pointer-sdk';

function FeaturePage() {
  const { trackEvent } = useUser();
  
  const handleFeatureUsage = () => {
    // Your feature logic here
    
    // Track the event
    trackEvent({
      eventType: 'FEATURE_USAGE',
      eventName: 'export_report',
      metadata: {
        reportType: 'analytics',
        format: 'csv',
        dataRange: '30_days'
      }
    });
  };
  
  return (
    <button onClick={handleFeatureUsage}>
      Export Report
    </button>
  );
}

Event structure

eventType
string
required

Category of the event (e.g., FEATURE_USAGE, ACCOUNT_UPDATE, WORKFLOW_COMPLETION)

eventName
string
required

Specific action or milestone (e.g., export_report, subscription_changed, completed_setup)

metadata
object

Optional additional context for the event, such as feature settings or workflow details

Authentication integration

app/layout.tsx
import { PointerProvider } from 'pointer-sdk';
import { getSession } from '@/lib/auth';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const session = await getSession();
  
  const userData = session?.user ? {
    userId: session.user.id,
    name: session.user.name,
    email: session.user.email,
    customData: {
      plan: session.user.plan
    }
  } : undefined;
  
  return (
    <html>
      <body>
        <PointerProvider 
          projectId={process.env.NEXT_PUBLIC_POINTER_PROJECT_ID!}
          userData={userData}
        >
          {children}
        </PointerProvider>
      </body>
    </html>
  );
}

Analytics and insights

User tracking data becomes available in your Pointer analytics dashboard, providing insights into:

  • User profiles: Profile information, session history, and feature usage
  • Behavior patterns: Flow completion rates, feature adoption, and engagement metrics
  • User segments: Group users by plan type, company, or custom data

To view user analytics, go to the Analytics section.

Data privacy and security

User data is automatically persisted in the browser’s localStorage to maintain identity across sessions.

Avoid storing sensitive information in the user’s customData field as it will be persisted to localStorage and could be accessible to client-side code.

Best practices

Troubleshooting

User data not appearing

If user tracking data isn’t showing up in your analytics:

  1. Verify user ID: Ensure you’re providing a valid, non-empty userId
  2. Check authentication flow: Confirm setUserData is called after successful login
  3. Review console errors: Look for JavaScript errors that might prevent tracking

Inconsistent user identification

When users appear as different entities in analytics:

  1. Check userId consistency: Ensure the same ID is used across sessions
  2. Review authentication logic: Verify user data is set correctly during login
  3. Clear localStorage: Test with cleared browser storage to eliminate cached data