GalachaProvider

The React context provider that boots the SDK and makes it available to the rest of your tree.

Install

npm install @galacha/react

Basic usage

import { GalachaProvider } from "@galacha/react";
 
<GalachaProvider projectKey={process.env.NEXT_PUBLIC_GALACHA_PROJECT_KEY!}>
  {children}
</GalachaProvider>

That's all you need for most apps. The Provider lazy-loads the recorder bundle on mount, calls init(), and exposes the useGalacha() hook to children.

Where to mount it

Once, as high in your tree as possible. Typically the root layout.

Next.js App Router

// app/layout.tsx
import { GalachaProvider } from "@galacha/react";
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <GalachaProvider projectKey={process.env.NEXT_PUBLIC_GALACHA_PROJECT_KEY!}>
          {children}
        </GalachaProvider>
      </body>
    </html>
  );
}

The Provider is already a client component (the bundle carries "use client"). Safe to drop into a server layout directly.

Next.js Pages Router

// pages/_app.tsx
import { GalachaProvider } from "@galacha/react";
 
export default function App({ Component, pageProps }: AppProps) {
  return (
    <GalachaProvider projectKey={process.env.NEXT_PUBLIC_GALACHA_PROJECT_KEY!}>
      <Component {...pageProps} />
    </GalachaProvider>
  );
}

Vite / CRA

// src/main.tsx
import { GalachaProvider } from "@galacha/react";
 
createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GalachaProvider projectKey={import.meta.env.VITE_GALACHA_PROJECT_KEY}>
      <App />
    </GalachaProvider>
  </StrictMode>,
);

Props

PropTypeDefaultRequiredPurpose
projectKeystringyesToken from the Galacha dashboard
childrenReactNodeyesYour app tree
apiUrlstringhttps://api.galacha.menoOverride the API endpoint
sdkUrlstringCDN defaultnoOverride the recorder URL
disabledbooleanfalsenoSkip loading entirely (tests)
debugbooleanfalsenoVerbose console logs
maskInputsbooleantruenoMask input values
captureNetworkbooleantruenoCapture fetch/XHR
captureErrorsbooleantruenoAuto-capture unhandled errors
captureConsolebooleantruenoCapture console.log/warn/error
flushIntervalMsnumber5000noBuffer flush cadence
flushMaxEventsnumber50noForce-flush after N events
sessionTimeoutMsnumber1800000noIdle ms before new session

With full config

<GalachaProvider
  projectKey="4d4b83bcd00a..."
  debug={process.env.NODE_ENV !== "production"}
  disabled={process.env.NODE_ENV === "test"}
  maskInputs={true}
  captureConsole={true}
  flushIntervalMs={3000}
  flushMaxEvents={100}
  sessionTimeoutMs={15 * 60 * 1000}
>
  <App />
</GalachaProvider>

First-mount wins

The Provider's config is frozen on first mount. Changing props at runtime does not re-init the SDK:

// ❌ Changing projectKey at runtime is a no-op
<GalachaProvider projectKey={userSelectedKey}>

Why: Galacha.init() is idempotent per page load. If you need to switch projects, reload the page or unmount/remount via a key prop:

<GalachaProvider key={projectKey} projectKey={projectKey}>
  <App />
</GalachaProvider>

The key change forces React to destroy the old Provider and mount a new one.

Safe with StrictMode / HMR / multiple Providers

The boot logic runs as a singleton on window.__galachaBoot. React StrictMode's double-invoke, HMR remounts, and multiple <GalachaProvider> instances on the same page all share the same boot state. Only one <script> tag is injected, only one Galacha.init() call fires.

Disabling in tests

<GalachaProvider projectKey="..." disabled={process.env.NODE_ENV === "test"}>
  <App />
</GalachaProvider>

With disabled: true, the Provider skips the script load and SDK init entirely. useGalacha() still returns a valid context value (ready: false, identify/stop become no-ops).

Debug logging

<GalachaProvider projectKey="..." debug>

Prints to the console:

[galacha/react] booting { sdkUrl: '...', projectKey: '4d4b83bcd00a…' }
[galacha/react] script injected https://sdk.galacha.me/sdk/latest/galacha.umd.js
[galacha/react] script onload
[galacha/react] init called. isReady: true

Related