@sheepit-ai/react
v1.0.0
Published
Sheepit React bindings — Provider, hooks, and components for feature flags, experiments, and analytics
Downloads
99
Maintainers
Readme
@goatech/react
React bindings for the GoaTech release-intelligence platform. A typed <GoaTechProvider>, hooks for flags/experiments/events, and a <TestProvider> for tests.
Install
npm install @goatech/react @goatech/sdk-jsQuickstart
// app/layout.tsx (Next.js) — any React root works
"use client";
import { GoaTech } from "@sheepit-ai/sdk-js";
import { GoaTechProvider } from "@sheepit-ai/react";
const gt = GoaTech.create({
apiKey: process.env.NEXT_PUBLIC_GOATECH_PUB_KEY!,
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<GoaTechProvider client={gt}>{children}</GoaTechProvider>
</body>
</html>
);
}// Use flags anywhere in the tree
"use client";
import { useFlag, useExperiment, useTrack } from "@sheepit-ai/react";
export function CheckoutButton() {
const track = useTrack();
const newCheckout = useFlag("new_checkout_flow", false);
const { variant } = useExperiment("checkout_copy");
return (
<button
onClick={() => track("checkout_started", { variant })}
className={newCheckout ? "new" : "classic"}
>
{variant === "bold" ? "Get It Now" : "Buy"}
</button>
);
}API
<GoaTechProvider client={gt}>
Pass a GoaTech instance (from @goatech/sdk-js) into your tree. Tests can substitute <TestProvider> from @goatech/react/test.
useFlag<T>(flagKey, defaultValue?)
Server-evaluated flag value. Fires $flag_exposure once per session.
useExperiment(experimentKey)
Returns { variant, payload }. Assignment is sticky per device.
useTrack()
Returns a stable track(eventName, properties?) function.
useGoaTech()
Returns the underlying GoaTech client. Use it for identity controls on login/logout:
const gt = useGoaTech();
gt.identify("user_abc123", { email: "[email protected]" }); // after login
gt.reset(); // after logoutComponents
<Feature flagKey="..." fallback={...}>
Render-prop wrapper around useFlag for binary or value-matched gates.
import { Feature } from "@sheepit-ai/react";
<Feature flagKey="new_checkout_flow" fallback={<LegacyCheckout />}>
<NewCheckout />
</Feature>;
// Match a specific value when the flag is non-boolean:
<Feature flagKey="cta_variant" match="bold" fallback={<DefaultCTA />}>
<BoldCTA />
</Feature>;<Experiment experimentKey="..." variants={{ ... }}>
Render the bucketed variant for an experiment. Assignment is sticky per device; $exposure fires automatically on first render.
import { Experiment } from "@sheepit-ai/react";
<Experiment
experimentKey="checkout_button_copy"
variants={{
control: <button>Buy</button>,
bold: <button>Get It Now</button>,
}}
fallback={<button>Buy</button>}
/>;
// Render-prop form for full access to the result + payload:
<Experiment experimentKey="hero_h1">
{({ variant, payload }) => <h1>{(payload as { headline: string }).headline}</h1>}
</Experiment>;<PageViewTracker pathname={...} searchParams={...} />
Mount inside a Next.js layout to fire $pageview whenever pathname or search params change. Pair with usePathname() + useSearchParams().
"use client";
import { PageViewTracker } from "@sheepit-ai/react";
import { usePathname, useSearchParams } from "next/navigation";
export function Analytics() {
const pathname = usePathname();
const searchParams = useSearchParams();
return <PageViewTracker pathname={pathname} searchParams={searchParams} />;
}<ErrorBoundary fallback={...}>
React error boundary that forwards render-time crashes to GoaTech as $error events with component_stack. Pair with the SDK's pre-React boot-error capture for full coverage.
import { ErrorBoundary } from "@sheepit-ai/react";
<ErrorBoundary fallback={<FatalErrorScreen />}>
<App />
</ErrorBoundary>;
// Render-prop form gives you the error + a reset callback:
<ErrorBoundary
fallback={({ error, reset }) => (
<div>
<p>{error.message}</p>
<button onClick={reset}>Try again</button>
</div>
)}
>
<App />
</ErrorBoundary>;Testing
import { TestProvider } from "@sheepit-ai/react/test";
render(
<TestProvider flags={{ new_checkout_flow: true }}>
<CheckoutButton />
</TestProvider>,
);Next.js
Works in both App Router and Pages Router. The provider is client-only ("use client") — put it inside a client component boundary.
License
MIT © GoaTech
