Skip to main content
A Next.js app can use both SDKs:
  • @glyphhq/node on the server — route handlers, server actions, and webhooks. Put payments, subscription changes, and other critical events here because delivery does not depend on a browser session.
  • @glyphhq/browser on the client — in-product actions and page views that only exist client-side.
If you only instrument one side, use the server. Add the browser SDK when page views or client-only actions provide useful context.

Environment variables

.env.local
Use glyph_test_... keys in development and glyph_pk_... in production. Create separate named keys for the server and browser. A browser key is publicly visible, so separation lets you rotate it without changing server deployments.

Server side

Create one shared client at module scope. Each server process gets one instance, allowing it to batch messages across requests:
lib/glyph.ts

Route handlers and server actions

Serverless runtimes can freeze the moment a response is sent, so flush before returning:
app/api/projects/route.ts
The same pattern applies inside server actions: track, await glyph.flush(), return.
Use the Node.js runtime (the default) for routes that send to Glyph. If a route opts into another runtime, verify it supports the timer and fetch APIs the SDK relies on before shipping.

Webhooks

Billing webhooks are a reliable place to capture payment and subscription events:
app/api/webhooks/stripe/route.ts

Profile on signup

Send the profile from the server when signup completes, such as in an auth callback or server action:

Client side

Manage the singleton in a client component near the root and initialize it only for signed-in users. Glyph only tracks known customers. Reinitializing or resetting disposes the previous client, clears its queue, and removes its timer and browser listeners:
components/glyph-provider.tsx
Render it from your root layout with the session’s user ID (from your auth library, server-side). Then track from any client component:

Page views

App Router navigation doesn’t reload the page, so track route changes with usePathname:
components/glyph-pageview.tsx
Track only product areas that add useful context; see page views worth capturing. App Router transitions preserve the page and its in-memory queue. A hard navigation or tab close only triggers a best-effort flush, so critical events should remain server-side.

Checklist

  1. Separate server and browser keys set through GLYPH_WRITE_KEY and NEXT_PUBLIC_GLYPH_WRITE_KEY in both .env.local and your deployment’s environment.
  2. Shared GlyphNode in lib/glyph.ts, with onError logging.
  3. await glyph.flush() before every response in route handlers, server actions, and webhooks.
  4. profile sent server-side at signup, with email.
  5. Client singleton initialized only for signed-in users; reset() on logout.
  6. Verified with a glyph_test_... key in the test environment before switching production to glyph_pk_....
Verify each item, then check the resulting customer timelines in the test environment.