React
Use the web SDK in React, Next.js and other React frameworks.
No separate React package yet
A dedicated @atrix.dev/analytics-react package with a provider and hooks is planned. Today React apps use
@atrix.dev/analytics-web directly, which is SSR-safe: every call is a no-op on the server. The patterns below
are all you need.
npm i @atrix.dev/analytics-webInitialise once
Call init once on the client, as early as you can. On the server it does nothing, so it is safe to call
from a module that is also rendered on the server.
"use client";
import * as atrix from "@atrix.dev/analytics-web";
import { type ReactNode, useEffect } from "react";
export function AnalyticsProvider({ children }: { children: ReactNode }) {
useEffect(() => {
atrix.init("atx_pk_eu_production_XXXXXXXXXXXXXXXXXXXXXX", { replay: { sampleRate: 0.2 } });
return () => void atrix.shutdown();
}, []);
return <>{children}</>;
}In the Next.js App Router, render <AnalyticsProvider> in your root layout. Pageviews for client-side
navigations are recorded automatically from the History API, so you do not need a router hook.
Identify on sign-in, reset on sign-out
import * as atrix from "@atrix.dev/analytics-web";
import { useEffect } from "react";
export function useIdentify(user: { id: string; plan: string } | null) {
useEffect(() => {
if (user) atrix.identify(user.id, { plan: user.plan });
}, [user]);
}
export function signOut() {
atrix.reset();
}A flag hook
onFlags calls back immediately when values are known and again after every reload, and returns an
unsubscribe function, which fits useSyncExternalStore:
import * as atrix from "@atrix.dev/analytics-web";
import { useSyncExternalStore } from "react";
export function useFlag(key: string): boolean {
return useSyncExternalStore(
(onChange) => atrix.onFlags(onChange),
() => atrix.isEnabled(key),
() => false,
);
}
export function useVariant(key: string): string | null {
return useSyncExternalStore(
(onChange) => atrix.onFlags(onChange),
() => atrix.getVariant(key),
() => null,
);
}import { useFlag } from "./flags";
export function Checkout() {
const newCheckout = useFlag("new-checkout");
return newCheckout ? <p>New checkout</p> : <p>Classic checkout</p>;
}To avoid a flicker on first render, pass values you already know (for example from your server) as
bootstrap: { flags: { … } } to init.
Tracking from components
Call atrix.track from event handlers. Keep event names stable and in snake_case, and send money as integer
minor units:
import * as atrix from "@atrix.dev/analytics-web";
export function BuyButton({ priceMinor }: { priceMinor: number }) {
return (
<button type="button" onClick={() => atrix.track("buy_clicked", { amount: priceMinor, currency: "USD" })}>
Buy
</button>
);
}Everything else, including options, consent and replay masking, is in the web SDK guide.