React and Next.js
One provider near the root, a hook to send events, and a page view on every route change
The React bindings ship inside the npm package as @sfere.io/sfere-sdk/react. React 17 or newer is supported. Use the bindings or the script-tag loader on a page, not both: each loads its own copy and every event would be sent twice.
Install#
npm install @sfere.io/sfere-sdkAdd the provider#
SfereProvider loads the SDK once per write key and host for the life of the page, including under StrictMode and hot reload.
| Hook | What it does |
|---|---|
useSfere() |
Returns the SDK instance: track, identify, page, reset, setConsent and more. |
usePageTracking(routeKey) |
Sends one page() each time routeKey changes. |
Examples#
import { useLocation } from "react-router-dom";
import { SfereProvider, usePageTracking, useSfere } from "@sfere.io/sfere-sdk/react";
function PageViews() {
const { pathname, search } = useLocation();
usePageTracking(pathname + search);
return null;
}
export default function App() {
return (
<SfereProvider writeKey="YOUR_WRITE_KEY" host="https://events.sfere.io">
<PageViews />
{/* your routes */}
</SfereProvider>
);
}
function AddToCartButton({ item }) {
const sfere = useSfere();
return (
<button onClick={() => sfere.track("add_to_cart", { currency: "USD", value: item.price, items: [item] })}>
Add to cart
</button>
);
}Create a client component for the provider and render it from app/layout.tsx. useSearchParams() needs a Suspense boundary.
"use client";
import { Suspense } from "react";
import { usePathname, useSearchParams } from "next/navigation";
import { SfereProvider, usePageTracking } from "@sfere.io/sfere-sdk/react";
function PageViews() {
const pathname = usePathname();
const search = useSearchParams().toString();
usePageTracking(search ? `${pathname}?${search}` : pathname);
return null;
}
export function Providers({ children }: { children: React.ReactNode }) {
return (
<SfereProvider
writeKey={process.env.NEXT_PUBLIC_SFERE_WRITE_KEY!}
host="https://events.sfere.io"
>
<Suspense fallback={null}><PageViews /></Suspense>
{children}
</SfereProvider>
);
}import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import { SfereProvider, usePageTracking } from "@sfere.io/sfere-sdk/react";
function PageViews() {
usePageTracking(useRouter().asPath);
return null;
}
export default function MyApp({ Component, pageProps }: AppProps) {
return (
<SfereProvider writeKey={process.env.NEXT_PUBLIC_SFERE_WRITE_KEY!} host="https://events.sfere.io">
<PageViews />
<Component {...pageProps} />
</SfereProvider>
);
}Server rendering#
During server rendering the provider returns an inert instance whose methods do nothing, so nothing is sent from the server and shared components can call useSfere() safely.
Options#
The provider accepts every load() option, plus disabled to turn tracking off (for example in tests). Options other than writeKey and host are read once, when the provider first mounts.