Developer

React bindings

Use DripProvider and all Apex SDK React hooks for assignments, variations, flags, tracking, revenue, and loading state.

Import React bindings from @drip-apex/sdk/react. The provider dynamically imports the browser SDK so React apps can avoid server-side DOM access during module evaluation.

DripProvider

tsx
import { DripProvider } from "@drip-apex/sdk/react";
 
export function StorefrontApp({ children }: { children: React.ReactNode }) {
  return (
    <DripProvider
      shopId="demo-shop"
      endpoint="https://events.drip-apex.com"
      platformHint="spa"
      spa={{ routerMode: "auto", domChangeTrigger: true }}
      onExperimentViewed={(assignment) => {
        console.log("Apex assignment", assignment.experimentId, assignment.variationId);
      }}
    >
      {children}
    </DripProvider>
  );
}

DripProvider accepts all InitConfig fields except it redefines onExperimentViewed as a React prop and requires children.

Assignment hooks

tsx
import { useAssignments, useExperiment, useLoading, useVariation } from "@drip-apex/sdk/react";
 
export function ProductHero() {
  const loading = useLoading();
  const allAssignments = useAssignments();
  const heroAssignment = useExperiment("product-hero-layout");
  const heroVariation = useVariation("product-hero-layout");
 
  if (loading) return null;
 
  return (
    <section data-active-apex={allAssignments.length > 0 ? "yes" : "no"}>
      <h1>
        {heroVariation?.id === "proof-led"
          ? "Built for confident purchase decisions"
          : "A better way to buy"}
      </h1>
      {heroAssignment ? <small>Variant: {heroAssignment.variationId}</small> : null}
    </section>
  );
}
HookReturnsUse
useExperiment(experimentId)Assignment or nullRead the assignment for an experiment ID or slug.
useVariation(experimentId)Variation summary or nullRender based on assigned variation ID and control state.
useAssignments()Assignment[]Inspect all active assignments.
useLoading()booleanHide assignment-dependent UI until provider initialization completes.

Feature flag hooks

tsx
import { useFeatureFlag, useFeatureFlagValue } from "@drip-apex/sdk/react";
 
export function CheckoutButton() {
  const progressUiEnabled = useFeatureFlag("checkout-progress-ui");
  const copy = useFeatureFlagValue("checkout-cta-copy", "Continue to checkout");
 
  return (
    <button data-progress-ui={progressUiEnabled ? "enabled" : "disabled"}>
      {String(copy)}
    </button>
  );
}
HookReturnsUse
useFeatureFlag(flagId)booleanReturns true for non-control flag assignments.
useFeatureFlagValue(flagId, fallback)Assigned value or fallbackReturns the assigned variation value or fallback.

Tracking hooks

tsx
import { useTrack, useTrackGoal, useTrackRevenue } from "@drip-apex/sdk/react";
 
export function AddToCartButton() {
  const track = useTrack();
  const trackGoal = useTrackGoal();
  const trackRevenue = useTrackRevenue();
 
  return (
    <button
      onClick={() => {
        track("add_to_cart", { product_id: "example-product" });
        trackGoal("add-to-cart-click", { surface: "product-card" });
        trackRevenue(49, { currency: "EUR", orderId: "order-preview" });
      }}
    >
      Add to cart
    </button>
  );
}
HookReturnsUse
useTrackGoal()(goalId, data?) => voidTrack a configured Apex goal.
useTrack()(type, data?) => voidTrack a custom event.
useTrackRevenue()(revenue, data?) => voidTrack revenue through the SDK.

Provider boundary

Every hook throws if used outside <DripProvider>. Keep the provider in your app shell so route-level components share one SDK initialization.