Developer

Vue and Nuxt bindings

Reactive Apex assignments, feature flags, tracking, and server-rendered Nuxt variants.

Import composables from @drip-apex/sdk/vue. Vue 3.5 or later is an optional peer dependency. The browser entry keeps Node signature verification out of client bundles.

Install

sh
npm install @drip-apex/sdk vue

These bindings ship in @drip-apex/sdk 0.4.0 and later. Upgrade any 0.3.0 installation before importing the ./vue export.

Plugin

ts
import { createApp } from "vue";
import { DripPlugin } from "@drip-apex/sdk/vue";
import App from "./App.vue";
 
createApp(App).use(DripPlugin, {
  shopId: "demo-shop",
  endpoint: "https://events.drip-apex.com",
  platformHint: "spa",
}).mount("#app");

If you already install the hosted snippet, use app.use(DripPlugin) without config. It reads the live window.drip runtime and connects when a delayed snippet initializes. provideDrip(config?, options?) establishes the same context for descendants from a component's setup function. Initialization errors are available through useDrip().error.

Assignment composables

vue
<script setup lang="ts">
import { useAssignments, useExperiment, useVariation, useLoading } from "@drip-apex/sdk/vue";
const assignments = useAssignments();
const hero = useExperiment("hero");
const variant = useVariation("hero");
const loading = useLoading();
</script>
 
<template>
  <h1 v-if="!loading">{{ variant?.id === 'treatment' ? 'New headline' : 'Original headline' }}</h1>
</template>
ComposableReturns
useAssignments()Ref<Assignment[]>
useExperiment(id)Ref<Assignment | null>
useVariation(id)Ref containing { id, isControl } or null
useLoading()Ref<boolean>

Refs update after runtime re-evaluation, including route changes, consent changes, and reInit. Vue templates unwrap refs; use .value in JavaScript.

Feature flag composables

vue
<script setup lang="ts">
import { useFeatureFlag, useFeatureFlagValue } from "@drip-apex/sdk/vue";
const enabled = useFeatureFlag("checkout-progress");
const copy = useFeatureFlagValue("checkout-copy", "Continue to checkout");
</script>
 
<template><button :data-progress="enabled">{{ copy }}</button></template>

useFeatureFlag returns a boolean ref. useFeatureFlagValue<T> returns the assigned value or the fallback in a ref. Choose T to match the flag's configured value type; the generic does not validate remote values.

Tracking composables

ts
import { useTrack, useTrackGoal, useTrackRevenue } from "@drip-apex/sdk/vue";
const track = useTrack();
const trackGoal = useTrackGoal();
const trackRevenue = useTrackRevenue();
 
function onPurchase(orderId: string) {
  track("checkout-complete");
  trackGoal("purchase");
  trackRevenue(49, { currency: "EUR", orderId });
}

Call these from client interactions after the runtime loads. They use the provider's runtime and its consent rules.

SSR with Nuxt

Use a universal plugin to pass Nuxt's request-scoped composables. Vue-only applications do not need a Nuxt dependency.

ts
// plugins/apex.ts
import { DripPlugin } from "@drip-apex/sdk/vue";
 
export default defineNuxtPlugin((nuxtApp) => {
  const event = import.meta.server ? useRequestEvent() : undefined;
  nuxtApp.vueApp.use(DripPlugin, undefined, {
    serverAssignments: event?.context.apexAssignments,
    nuxt: { useRequestHeaders, useCookie, useState },
  });
});
vue
<script setup lang="ts">
import { useApexVariant } from "@drip-apex/sdk/vue";
const variant = useApexVariant("hero");
</script>
<template><h1>{{ variant?.id === 'treatment' ? 'New headline' : 'Original headline' }}</h1></template>

useApexVariant returns a ref containing { id, isControl } or null. It renders the useState("apex-assignments") payload during hydration, then adopts live assignments. A visitor without a drip_uid cookie and without forwarded assignments receives no server assignment; the client buckets later.

readServerAssignments(headers, { drip_uid }, options) verifies forwarded decisions when options.ingestToken is supplied. It never throws on untrusted input: a missing or invalid signature, a malformed or duplicated header, an oversized envelope, an unsupported version, or a missing token returns { assignments: [], source: "none", rejected } with the reason (missing_signature, invalid_signature, malformed, duplicate_header, oversized, unsupported_version, no_token, or server_only when the browser bundle is asked to verify) and no unsigned fallback. Read rejected before treating an empty list as "no experiments". The signature is hex HMAC-SHA256 over the exact JSON header bytes. Without a header it uses the cookie and the shared SDK bucketing kernel over options.experiments.

Pass only experiments already eligible for this request to cookie bucketing. This helper does not evaluate browser targeting, sticky assignment storage, exclusion groups, schedules, or commerce authorization. Prefer verified forwarded assignments for those configurations. Never expose the ingest token through public runtime config or the Nuxt payload. See the Nitro verification example.

Provider boundary

Every composable requires DripPlugin or an ancestor calling provideDrip. Install the plugin once per Vue app, or once per Nuxt request. Component-scoped providers dispose on scope teardown; the plugin disposes when the app unmounts. Request decisions are never stored in module globals.