Thisbefine
React

Analytics Component

The drop-in component that powers everything

Analytics Component

The <Analytics /> component is your one-stop shop for adding Thisbefine to your app. Drop it in, configure it, forget about it.

No context providers. No wrapping your entire app. Just one component.

Import

// For Next.js App Router
import { Analytics } from '@thisbefine/analytics/next';

// For React (Vite, CRA, etc.)
import { Analytics } from '@thisbefine/analytics/react';

Basic Usage

Add it to your root layout. Doesn't matter if it's before or after children:

app/layout.tsx
import { Analytics } from '@thisbefine/analytics/next';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <Analytics apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!} />
      </body>
    </html>
  );
}

That's it. Your app now tracks pageviews automatically.

Props

Prop

Type

Configuration Styles

Zero Config (Next.js)

Set the environment variable and you're done:

.env.local
NEXT_PUBLIC_TBF_API_KEY=tif_your_api_key
app/layout.tsx
<Analytics />

The component reads from NEXT_PUBLIC_TBF_API_KEY automatically. No props needed.

Explicit API Key

Pass the key directly:

<Analytics apiKey="tif_your_api_key" />

Or from environment:

<Analytics apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!} />

Full Configuration

For when you want to tweak everything:

<Analytics
  apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!}
  debug={process.env.NODE_ENV === 'development'}
  trackPageviews={true}
  config={{
    flushAt: 20,
    flushInterval: 10000,
    sessionTimeout: 1800000,
    respectDNT: true,
    maxRetries: 3,
    errors: {
      enabled: true,
      captureConsoleErrors: false,
      captureNetworkErrors: true,
      maxBreadcrumbs: 25,
    },
  }}
/>

Next.js vs React

Both exports have the same API, but the Next.js version is optimized for App Router:

Feature@thisbefine/analytics/next@thisbefine/analytics/react
Automatic pageviewsUses usePathname + useSearchParamsListens to popstate events
SSR safeYesYes
Zero configReads NEXT_PUBLIC_TBF_API_KEYRequires apiKey prop

Rule of thumb: Use /next for Next.js, /react for everything else.

Automatic Pageview Tracking

By default, the component tracks pageviews automatically:

  • Next.js: Every client-side navigation via usePathname
  • React: Browser back/forward via popstate

To disable automatic tracking:

<Analytics trackPageviews={false} />

Then track manually with the usePage hook:

import { usePage } from '@thisbefine/analytics/next';

const page = usePage();
page('/custom-page', { section: 'marketing' });

Environment-Specific Setup

Different configs for different environments:

app/layout.tsx
import { Analytics } from '@thisbefine/analytics/next';

const isDev = process.env.NODE_ENV === 'development';
const isPreview = process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics
          apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!}
          debug={isDev || isPreview}
          config={{
            flushAt: isDev ? 1 : 20,  // Immediate in dev
            errors: {
              enabled: !isDev,  // Only in prod
              captureNetworkErrors: !isDev,
            },
          }}
        />
      </body>
    </html>
  );
}

Conditional Loading

Want to wait for cookie consent? Respect GDPR? Good human:

'use client';

import { Analytics } from '@thisbefine/analytics/next';
import { useCookieConsent } from '@/hooks/use-cookie-consent';

export const ConditionalAnalytics = () => {
  const { hasConsented } = useCookieConsent();

  if (!hasConsented) {
    return null;  // No consent, no tracking
  }

  return <Analytics apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!} />;
};

Disabling in Tests

Your tests don't need analytics:

const AnalyticsWrapper = () => {
  if (process.env.NODE_ENV === 'test') {
    return null;
  }

  return <Analytics apiKey="tif_xxx" />;
};

Or mock everything:

__tests__/setup.tsx
import { vi } from 'vitest';

vi.mock('@thisbefine/analytics/next', () => ({
  Analytics: () => null,
  useTrack: () => vi.fn(),
  useIdentify: () => vi.fn(),
  // Mock whatever hooks you use
}));

TypeScript

Everything's typed. Import AnalyticsConfig for full type safety:

import { Analytics } from '@thisbefine/analytics/next';
import type { AnalyticsConfig } from '@thisbefine/analytics';

const config: Partial<AnalyticsConfig> = {
  flushAt: 10,
  debug: true,
};

<Analytics
  apiKey={process.env.NEXT_PUBLIC_THISBEFINE_API_KEY!}
  config={config}
/>

Self-Hosting?

If you're running your own Thisbefine instance:

<Analytics
  apiKey="tif_xxx"
  host="https://analytics.yourcompany.com"
/>

When self-hosting, make sure your API implements the same endpoints. Check the API Reference for details.

On this page