This page builds a Next.js App Router app with two packages. Grain Tag (@grainql/tag) runs in
the browser for page views, clicks, heatmaps, and the user ID. Analytics Web
(@grainql/analytics-web) runs on the server with the SERVER_SIDE strategy. Each block
names its package. For the Pages Router, read Next.js.
Environment variables
Put these in .env.local. Next.js sends every NEXT_PUBLIC_ variable to the browser. The
secret key has no prefix, so it stays on the server.
Do not put the secret key in a NEXT_PUBLIC_ variable. Anyone who opens the site can read it.
Grain Tag in the root layout
Grain Tag runs in the browser. A Client Component calls init one time. init returns a no-op
stub outside a browser, so the import is safe in a server render.
Route changes
Grain Tag (@grainql/tag) tracks the first page view and every App Router navigation. The
App Router navigates through the History API, so a route change needs no component.
If you set enablePageViews: false in init and track page views yourself, read the path from
usePathname.
Identify with NextAuth
Grain Tag (@grainql/tag) attaches the user ID to every later event after identify. Read the
session from NextAuth and call identify when it holds a user. Grain Tag has no method that
clears the user ID.
identify called before init is queued and replayed after initialization. Read
Identify users.
A client event
Call track from a Client Component.
A server-side event
A route handler uses Analytics Web (@grainql/analytics-web) with the SERVER_SIDE strategy
and the secret key. Create the client one time at module scope.
The { flush: true } option sends the event before the function returns. Without it, a
serverless function can stop before the batch timer fires, and the event is lost. The userId
field of the event object attaches the event to the user who placed the order.
auth is the NextAuth helper of your app. Read Node.js and servers and
Authentication.