<PulsoraProvider>#

<PulsoraProvider> bootstraps Pulsora in React applications and exposes the tracker through context. Wrap your application once—usually in the root layout.

import { PulsoraProvider } from '@pulsora/react';

export function AppProviders({ children }: { children: React.ReactNode }) {
  return (
    <PulsoraProvider
      config={{
        apiToken: process.env.NEXT_PUBLIC_PULSORA_TOKEN!,
        autoPageviews: true,
        debug: process.env.NODE_ENV === 'development',
      }}
    >
      {children}
    </PulsoraProvider>
  );
}

Props#

Prop Type Required Description
config PulsoraConfig Same options as new Pulsora().init().
children ReactNode Your application tree.

PulsoraConfig mirrors the core SDK:

interface PulsoraConfig {
  apiToken: string;
  endpoint?: string;
  debug?: boolean;
  autoPageviews?: boolean;
  maxRetries?: number;
  retryBackoff?: number;
}

Accessing the Context#

Use usePulsora() to access the tracker instance. Until the provider finishes initializing, the hook returns null, so guard your calls:

import { usePulsora } from '@pulsora/react';

function CheckoutButton() {
  const pulsora = usePulsora();

  const handleCheckout = async () => {
    const fingerprint = await pulsora?.getVisitorFingerprint();
    const sessionId = pulsora?.getSessionId();
    // Use for server-side attribution
  };

  return <button onClick={handleCheckout}>Checkout</button>;
}

If you need context metadata (isReady, error), read it directly from PulsoraContext:

import { useContext } from 'react';
import { PulsoraContext } from '@pulsora/react';

function StatusBadge() {
  const context = useContext(PulsoraContext);
  if (!context) return null;

  const { isReady, error } = context;

  if (error) return <span className="text-red-500">Error</span>;
  if (!isReady) return <span className="text-muted-foreground">Loading</span>;

  return <span className="text-emerald-600">Ready</span>;
}

Avoid Nesting Providers#

Use a single provider at the top-level:

// ✅ Good
<PulsoraProvider config={{ apiToken: 'pub_123' }}>
  <App />
</PulsoraProvider>

// ❌ Bad - duplicate providers create multiple trackers
<PulsoraProvider config={{ apiToken: 'pub_123' }}>
  <Layout>
    <PulsoraProvider config={{ apiToken: 'pub_123' }}>
      <App />
    </PulsoraProvider>
  </Layout>
</PulsoraProvider>

Handling Initialization Errors#

If initialization fails (e.g. missing token, SSR misuse), the provider surfaces the error via context and logs it to the console.

const { error } = usePulsoraContext();

if (error) {
  return (
    <Alert variant="destructive">
      <AlertTitle>Analytics unavailable</AlertTitle>
      <AlertDescription>{error.message}</AlertDescription>
    </Alert>
  );
}

Provider Placement#

  • React Router — Wrap <BrowserRouter> so analytics sees route changes.
  • Next.js App Router — Wrap the root layout (see SSR guide).
  • Remix — Wrap the <Outlet /> tree in root.tsx.
  • Storybook / Docs — Wrap only demos that should emit analytics.

Continue with the hook reference to track events and pageviews: Hooks Reference →