Developer

Install and quickstart the Apex SDK

Choose the hosted script snippet or npm package, initialize Apex, and send your first SDK events.

The Apex SDK runs experiments, applies DOM mutations, evaluates flags, and sends storefront events to the Apex Worker. Use the hosted script for most storefront installs. Use the npm package when your app needs typed code-owned experiments, React bindings, or direct module imports.

Prerequisites

  • An Apex shop identifier from the installation screen.
  • The public Worker endpoint, usually https://events.drip-apex.com.
  • For npm usage, Node.js 18 or newer in your storefront build pipeline (the SDK package itself targets external consumers; developing inside the Apex monorepo requires Node.js 22.22+).

Hosted script

Add the hosted SDK directly in <head> and initialize it with a placeholder shop ID. Do not load it through a tag manager or place the script behind a consent gate: late loading prevents the anti-flicker guard from protecting the first paint. Consent should gate Apex storage and tracking through setConsent, not script delivery.

html
<script>
  window.drip = window.drip || [];
  window.Drip = window.Drip || {
    init(config) { window.drip.push({ type: "init", config }); },
    track(type, data) { window.drip.push({ type: "track", event: type, data }); },
    trackGoal(goalId, data) { window.drip.push({ type: "trackGoal", goalId, data }); },
    setConsent(granted) { window.drip.push({ type: "setConsent", granted }); }
  };
</script>
<script async src="https://sdk.drip-apex.com/drip.js"></script>
<script>
  Drip.init({
    shopId: "demo-shop",
    endpoint: "https://events.drip-apex.com"
  });
</script>

Use this path for Shopify theme snippets, Shopware plugins, WooCommerce templates, static storefronts, or headless sites where Apex should own assignment, anti-flicker, pageview tracking, and mutation delivery.

Headless / strict CSP

On a storefront whose script-src uses 'strict-dynamic' and a per-request nonce, host allowlisting alone does not authorize Apex. Put the same server-generated nonce on the shop-specific Apex loader tag (never hard-code or reuse a nonce). The /s/<shopId>.js snippet self-initializes — do not add the window.Drip.init queue shim here; that shim is only for the generic hosted drip.js flow, and including it makes the loader detect an existing runtime and skip loading the real SDK:

html
<script nonce="<per-request-nonce>" src="https://events.drip-apex.com/s/<shopId>.js"></script>

If an existing integration must keep the generic hosted drip.js flow, put that same nonce on all three parser-inserted script blocks — the queue bootstrap, loader, and Drip.init call. Under strict-dynamic, noncing the external loader does not authorize its inline siblings:

html
<script nonce="<per-request-nonce>">
  window.drip = window.drip || [];
  window.Drip = window.Drip || {
    init(config) { window.drip.push({ type: "init", config }); },
    track(type, data) { window.drip.push({ type: "track", event: type, data }); },
    trackGoal(goalId, data) { window.drip.push({ type: "trackGoal", goalId, data }); },
    setConsent(granted) { window.drip.push({ type: "setConsent", granted }); }
  };
</script>
<script nonce="<per-request-nonce>" async src="https://sdk.drip-apex.com/drip.js"></script>
<script nonce="<per-request-nonce>">
  Drip.init({
    shopId: "demo-shop",
    endpoint: "https://events.drip-apex.com"
  });
</script>

The trusted Apex snippet propagates that nonce when its delivery policy loads a secondary SDK bundle. Experiment JavaScript files created by the trusted SDK also inherit trust through CSP strict-dynamic; npm-imported SDK code is part of your already-authorized application bundle and has no separate loader tag.

If Google Tag Manager is already loaded by a nonced tag, it can install Apex as a Custom HTML tag and the trusted GTM execution chain authorizes the Apex script. This trades away early anti-flicker protection, so use the direct synchronous nonced tag when first-paint mutation delivery matters.

The browser must also be allowed to send events. Add exactly this origin to the site's existing connect-src directive:

text
https://events.drip-apex.com

Without that client-side CSP edit, assignment may run but every Apex event POST is blocked; Apex cannot work around it. The standard anti-flicker style works unchanged when the existing policy allows inline styles (for example style-src 'unsafe-inline'). Edge-injection's x-drip-csp-nonce path applies only when Apex proxies and rewrites the HTML response, not when Oxygen or another headless origin serves the page. See the headless strict-CSP runbook for the complete install-path checklist.

Flicker contract

The default scoped anti-flicker guard hides only elements that an active experiment can change. Apex reveals them as soon as mutations resolve. The guard has a 1200ms safety cap, so a failed config request or missing selector cannot leave the storefront hidden indefinitely.

Hydrating Nuxt and Next.js storefronts can keep immediate application with next-frame correction, or opt into applying after hydration. See SSR framework coexistence for the timing modes and handshake hooks.

npm package

Install the SDK when you want module imports:

bash
npm install @drip-apex/sdk

Initialize with fetched experiments:

ts
import { init, track, trackGoal } from "@drip-apex/sdk";
 
init({
  shopId: "demo-shop",
  endpoint: "https://events.drip-apex.com",
  trackingStart: "idle"
});
 
track("add_to_cart", {
  product_id: "gid://shopify/Product/example",
  value: 49,
  currency: "EUR"
});
 
trackGoal("product-page-cta-click", {
  source: "custom-button"
});

Initialize with local experiments:

ts
import { defineExperiment, init } from "@drip-apex/sdk";
 
const heroCopy = defineExperiment({
  slug: "homepage-hero-copy",
  name: "Homepage hero copy",
  variations: [
    { id: "control", weight: 0.5, isControl: true },
    {
      id: "proof-copy",
      weight: 0.5,
      mutations: [
        { selector: "[data-hero-title]", action: "text", text: "Trusted by growing teams" }
      ]
    }
  ]
});
 
init({
  experiments: [heroCopy],
  endpoint: "https://events.drip-apex.com"
});

Track your first conversion

ts
import { trackRevenue } from "@drip-apex/sdk";
 
trackRevenue(89.99, {
  orderId: "order-example-1001",
  currency: "EUR"
});

trackRevenue sends a goal event with the reserved __revenue__ goal ID for each active assignment.