Docs

Pairing with backend SDKs

Auto-attach session context to server-side SDK calls via cookies

Last updated:

When the Insights SDK runs on your frontend, it writes two first-party cookies that your server-side SDKs can consume automatically:

typescript
// The Insights SDK writes two first-party cookies on every page where it runs:
// - ss_vid: persistent visitor ID (1 year)
// - ss_sid: current recording session ID (session-scoped, rotates when the
//           backend seals the session)

The server-side SDKs (@sessionsight/goals, @sessionsight/flags, @sessionsight/feedback, @sessionsight/split-testing) expose a forRequest(req) helper. Pass it the inbound HTTP request and it auto-attaches the current recording session’s sessionId to every subsequent call. Goals, feedback, and split-testing are session-scoped (the backend resolves visitor and user identity from the session), so only sessionId flows in the event payload. The flags SDK additionally reads ss_vid into its evaluation context for segment_match targeting rules.

Framework examples

The examples below use SessionSightGoals to keep the snippets short; the same forRequest(req) pattern works on every server SDK.

Node / Express / Fastify / Koa

typescript
// Express / Fastify / Koa / raw Node
app.post('/signup', async (req, res) => {
  await SessionSightGoals.forRequest(req).increment('user-signups');
  res.json({ ok: true });
});

Next.js

App Router
// Next.js App Router (route handler receives a native Request)
export async function POST(req) {
  await SessionSightGoals.forRequest(req).increment('user-signups');
  return Response.json({ ok: true });
}
Pages Router
// Next.js Pages Router (req.cookies is pre-parsed)
export default async function handler(req, res) {
  await SessionSightGoals.forRequest(req).increment('user-signups');
  res.json({ ok: true });
}

SvelteKit

typescript
// SvelteKit (pass `request` or `cookies`; both detected)
export async function POST({ request }) {
  await SessionSightGoals.forRequest(request).increment('user-signups');
  return new Response(JSON.stringify({ ok: true }));
}

You can pass either request (native Request) or cookies (SvelteKit’s Cookies object). forRequest detects both shapes.

Nuxt 3

typescript
// Nuxt 3 / h3 (pass the event directly)
export default defineEventHandler(async (event) => {
  await SessionSightGoals.forRequest(event).increment('user-signups');
  return { ok: true };
});

Pass the h3 event directly. forRequest digs into event.node.req.headers.cookie for you.

Hono / Cloudflare Workers / Deno / Bun / Remix

typescript
// Hono / Cloudflare Workers / Deno / Bun (pass the native Request)
app.post('/signup', async (c) => {
  await SessionSightGoals.forRequest(c.req.raw).increment('user-signups');
  return c.json({ ok: true });
});

Anything that exposes a native Request works the same way. For Remix loaders/actions, pass request from the handler args.

Accepted request shapes

forRequest(req) duck-types across frameworks so you can pass whatever feels natural:

ShapeExamples
cookies.get('ss_vid') methodSvelteKit Cookies, Koa ctx.cookies
req.cookies mapExpress + cookie-parser, Next.js Pages Router, Fastify + @fastify/cookie
req.headers.get('cookie') (Fetch-style)Next.js App Router, SvelteKit request, Hono, Remix, Workers, Deno, Bun
req.headers.cookie (Node-style)raw Node, older Express, Koa, Fastify
event.node.req.headers.cookieNuxt 3 / h3
Raw cookie header stringEscape hatch for anything else

Explicit per-call sessionId (or visitorId for flags) always wins over the bound cookie value, so you can override when needed.

Session rotation

The ss_sid cookie rewrites automatically when the backend seals a session (analytics computed, archival pending). It also rewrites on tab focus, so whichever tab the user is currently interacting with owns the cookie. Backend SDK calls pick up the fresh id on the next request with no extra work from the host.

Multi-tab behavior

Each tab mints its own session id. The ss_sid cookie is last-writer-wins with focus-wins semantics: a server request from either tab reads the most-recently-active tab’s session id. If exact per-tab precision matters for your integration, forward the session id through an explicit header instead of relying on the cookie.