Chapter 03 · 5 min

Installing the SDK and verifying events

Client and server, one identity, and the green tick that means it is live.

See it in the demo. See the events arriving.See the events arriving

The SDK has two halves. On the client, @trevosdk/react resolves variants and reports exposures and events. On the server, @trevosdk/node resolves variants for server-rendered code and records the conversions that must be authoritative — an order, a subscription — idempotently. In Next.js, @trevosdk/nextjs ties them together with a middleware that gives every visitor a stable trevo_id cookie before the page renders, so the server and the client agree on one identity and the first paint is already the right variant.

npm install @trevosdk/nextjs @trevosdk/react @trevosdk/node

// middleware.ts
export { middleware } from '@trevosdk/nextjs';
export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)'] };

// app/layout.tsx
import { getTrevoBootstrap } from '@trevosdk/nextjs';
import { TrevoProvider } from '@trevosdk/react';

export default async function Layout({ children }) {
  const bootstrap = await getTrevoBootstrap();
  return (
    <TrevoProvider apiKey={process.env.NEXT_PUBLIC_TREVO_API_KEY} bootstrap={bootstrap}>
      {children}
    </TrevoProvider>
  );
}

Tracking the funnel

Page views are automatic. Everything else is a track() call with the event name your funnel uses. In Terra & Twine, add_to_cart fires from the product page button, checkout_started from the cart, and purchase_completed on the client — while the server records order_recorded with an insertId so a retried request never counts twice.

// client
trevo.track('add_to_cart', { product: slug, value: priceCents / 100 });

// server (app/api/checkout/route.ts)
trevo.track('order_recorded', { anonymousId }, { orderId, value }, { insertId: orderId });

Where the key goes

The key comes from Settings → SDK keys in the dashboard, and each half of the SDK wants a different class of key. The browser gets the publishable tsk_live_… key in a public env var your bundler compiles into the JS — NEXT_PUBLIC_TREVO_API_KEY on Next.js, VITE_TREVO_API_KEY on Vite. Servers get a secret tsk_secret_… key in TREVO_SECRET_KEY; it must never reach a browser, and the API rejects it if it ever does. One gotcha catches nearly everyone: hosts apply env changes to new deployments only, so after adding or rotating a key, redeploy — until then the live build keeps the old key and its events are rejected.

Verifying the first event

The dashboard shows a “receiving events” signal the moment the first event arrives, and a config heartbeat before that, so “SDK running, nothing tracked yet” is distinguishable from “SDK not installed”. If the first event does not arrive: check that the API key is public-prefixed and set in the environment the build uses, that the middleware matcher covers the route, and that an ad blocker is not swallowing the ingestion request in your own browser.