Next.js Installation Guide
Last researched 2026-08-26
This is the canonical Virent installation guide for Next.js projects. It covers Human Analytics browser tracking and AI Analytics server-side crawler tracking.
Research Notes#
- Next.js 16 App Router supports global third-party scripts through
next/scriptin layouts. - Next.js 16 renamed the
middleware.tsfile convention toproxy.ts. New AI Analytics installs should useproxy.ts. - Proxy runs before routes render and should use a matcher that excludes static assets and framework internals.
Primary references:
- https://nextjs.org/docs/app/guides/scripts
- https://nextjs.org/docs/app/api-reference/file-conventions/proxy
Human Analytics#
Install Human Analytics in app/layout.tsx so the browser script loads on every App Router route.
TSX
import Script from "next/script"export default function RootLayout({ children }) { return ( <html lang="en"> <body> {children} <Script src="https://app.virent.app/js/script.js" data-write-key="vha_pk_..." strategy="afterInteractive" /> </body> </html> )}Use the npm SDK only when custom product events, identities, or goals are needed.
SH
pnpm add @virent.app/sdk@^0.2.0TS
import { identify, initVirent, pageview, trackEvent, trackGoal } from "@virent.app/sdk/browser"initVirent({ writeKey: "vha_pk_..." })await pageview({ path: "/pricing" })await trackEvent({ name: "signup_started", properties: { plan: "pro" } })await identify({ userId: "customer_123", traits: { plan: "pro" } })await trackGoal({ name: "signup_completed", idempotencyKey: "order_123" })Best practices:
- Use
next/scriptinstead of a raw script tag in React layouts. - Keep
strategy="afterInteractive"for normal analytics so hydration is not blocked. - Keep the publishable key in
data-write-key; do not use the server secret in client code. - If Content Security Policy is enabled, allow the Virent origin in
script-srcandconnect-src.
Verification:
- Open a production or preview page and verify
/js/script.jsloads. - Navigate between App Router routes and confirm pageview requests are sent.
- Refresh Virent installation status and confirm Human Analytics is receiving events.
Troubleshooting:
- If the script is absent, confirm it is in the root layout used by the route.
- If the browser blocks the script, update CSP in
next.config.js,vercel.json,proxy.ts, or the hosting platform. - Localhost traffic is skipped by default. Add
data-allow-localhost="true"only for intentional local testing.
AI Analytics#
Install AI Analytics in proxy.ts at the project root or src/proxy.ts if the app uses a src directory.
SH
pnpm add @virent.app/sdk@^0.2.0ENV
VIRENT_SITE_ID=site_...VIRENT_INGEST_SECRET=vha_sk_...VIRENT_INGEST_ENDPOINT=https://app.virent.app/v1/ingest/botTS
// proxy.tsimport { createVirentBotProxy } from "@virent.app/sdk/next"export const proxy = createVirentBotProxy({ siteId: "site_...", writeKey: process.env.VIRENT_INGEST_SECRET!, trustedProxy: "vercel",})export const config = { matcher: [ "/((?!api|_next/static|_next/image|favicon.ico|robots.txt|sitemap.xml|.*\\.(?:png|jpg|jpeg|gif|svg|ico|webp|css|js|map)$).*)", ],}Best practices:
- Use
proxy.tsfor Next.js 16+ rather than creating newmiddleware.tscode. - Keep the matcher exclusions for API routes, static assets, image optimization, favicons, robots, sitemaps, and common file extensions.
- Store
VIRENT_INGEST_SECRETonly in server environment variables. - Use
trustedProxy: "vercel"on Vercel so the SDK can hash the real client IP without trusting arbitrary forwarding headers elsewhere. - Do not depend on React component state or mutable globals from Proxy.
Verification:
SH
curl -A "GPTBot" https://your-domain.com/- Confirm the request reaches
proxy.ts. - Confirm Virent receives crawler events.
- Refresh Virent installation status and confirm AI Analytics is receiving crawler events.
Troubleshooting:
- If every static asset creates events, tighten the matcher exclusions.
- If no events arrive, confirm
proxy.tsis at the same level asapporpages. - If the secret is masked in the UI, rotate and reveal the key before installing.