Thisbefine
Common Pitfalls

Common Pitfalls

Mistakes we've all made (so you don't have to)

Common Pitfalls


1. SSR / Hydration Issues

window is not defined or document is not defined

The SDK needs a browser. Use useEffect or check for window:

useEffect(() => {
  getAnalytics()?.track('page_loaded');
}, []);

if (typeof window !== 'undefined') {
  getAnalytics()?.track('event');
}

2. Invalid API Key

Invalid API key format

API keys must start with tif_. Copy the full key from your dashboard.


3. Missing Analytics Component

Analytics not initialized. Add <Analytics /> to your app.

Add <Analytics /> to your root layout before using hooks.


4. Identify Timing

Events before identify() aren't linked to the user

Call identify() immediately after login, before tracking events:

const handleLogin = async (credentials) => {
  const user = await login(credentials);
  identify(user.id, { email: user.email });
  track('login_completed');
  router.push('/dashboard');
};

5. Forgetting Reset on Logout

Next user's events attributed to previous user

Always call reset() on logout:

const handleLogout = async () => {
  await logout();
  reset();
  router.push('/login');
};

6. Do Not Track is Enabled

Issue: No events being tracked at all

What happened: We respect Do Not Track by default. If the user's browser has DNT enabled, we don't track. That's the whole point.

The fix: First, check if this is intentional (it might be!):

// Check the status
const analytics = getAnalytics();
console.log('Opted out:', analytics?.isOptedOut());

// If you really want to ignore DNT (please reconsider):
<Analytics
  apiKey="tif_xxx"
  config={{
    respectDNT: false,  // Not recommended, but it's your call
  }}
/>

7. Events Not Appearing in Dashboard

Issue: You sent events but don't see them

What happened: Could be a few things.


8. Page Navigation Not Tracked

Issue: Pageviews missing in SPA

What happened: For plain React apps, trackPageviews={true} only catches browser back/forward buttons (popstate). It doesn't know about your client-side router.

The fix: Use @thisbefine/analytics/next for Next.js - it handles this automatically. For other frameworks, manually track route changes:

// Plain React with React Router
import { useLocation } from 'react-router-dom';
import { usePage } from '@thisbefine/analytics/react';
import { useEffect } from 'react';

const PageTracker = () => {
  const page = usePage();
  const location = useLocation();

  useEffect(() => {
    page(location.pathname);
  }, [location, page]);

  return null;
};

// Add alongside your Analytics component
<App />
<PageTracker />
<Analytics apiKey="tif_xxx" />

9. Session Timeout Too Short

Issue: Too many sessions for long-running apps

What happened: Default is 30 minutes of inactivity = new session. If users keep tabs open all day (dashboard apps, dev tools), you get fragmented sessions.

The fix:

<Analytics
  apiKey="tif_xxx"
  config={{
    sessionTimeout: 7200000, // 2 hours
  }}
/>

10. Events Lost on Page Unload

Issue: Events not sent when navigating away

What happened: User clicks an external link. Events in the queue never get sent because the page unloaded.

The SDK uses sendBeacon automatically on unload, but for navigation you control:

The fix:

const handleExternalLink = async (url: string) => {
  // Flush the queue first
  await getAnalytics()?.flush();

  // Now safe to leave
  window.location.href = url;
};

11. TypeScript Type Errors

Issue: TS complaining about custom properties

What happened: TypeScript being TypeScript.

The fix: Properties are Record<string, unknown>, so anything goes:

// ✅ This works
track('event', {
  customProp: 'value',
  nested: { deep: true },
  array: [1, 2, 3],
});

// For strict typing, wrap it:
interface SignupProperties {
  source: 'header' | 'footer' | 'modal';
  referrer?: string;
}

const trackSignup = (props: SignupProperties) => {
  track('signup_clicked', props);
};

12. Multiple Analytics Instances

Issue: Weird duplicate events or missing data

What happened: You added multiple <Analytics /> components. Now you have multiple instances fighting each other.

The fix: One component. In one place. That's it.

// ✅ Correct - one Analytics component
<App />
<Analytics apiKey="tif_xxx" />

// ❌ What are you doing
<Analytics apiKey="tif_xxx" />
<SomeComponent />
<Analytics apiKey="tif_xxx" />  // Why?

Still Stuck?

If you've tried everything and it's still not working:

  1. Enable debug mode - see what's actually happening
  2. Check browser console - look for errors
  3. Check Network tab - are requests failing?
  4. Verify the API key - is it the right one?
  5. Check your dashboard - maybe events are there with different names?

Still nothing? Open an issue on GitHub. We're friendly.

On this page