How to Add Analytics to Next.js App: App Router Guide

Learn how to add GDPR-compliant analytics to your Next.js app with App Router. Step-by-step guide using Litlyx for privacy-first tracking.

Flat-lay workspace photograph showing Next.js analytics integration setup with an open notebook, smartphone displaying Litlyx dashboard, cod

, -

How to Add Analytics to a Next.js App (App Router, 2026)

What You Are Building and Why It Matters

By the end of this tutorial, you will have a Next.js 14+ App Router project with fully working pageview tracking and custom event analytics, all without a single line of messy script-tag hacking. Getting there requires a few extra steps compared to a plain HTML site, and understanding why those steps matter will save you hours of debugging.

Standard script-tag approaches break in Next.js for two interconnected reasons. First, the App Router renders server components by default, which means any analytics code that tries to access window or document will throw a runtime error before the browser ever sees the page. Second, SPA navigation in Next.js does not trigger full page loads or native browser pageview events, so a script dropped into the document head simply stops counting after the first visit. Those two issues together make a proper integration essential, not optional.

Throughout this tutorial, we use Litlyx as our analytics platform. It is Privacy-first analytics built for exactly this kind of setup: EU-hosted, GDPR-compliant, no personal data collected, and fast to configure.

Before starting, make sure you have the following ready:

  • Node 18 or higher installed
  • An existing Next.js App Router project (Next.js 14+)
  • A free Litlyx account from litlyx.com

Why Does Adding Analytics to Next.js Require Extra Steps?

Honestly, adding analytics to a Next.js App Router project is not as simple as dropping a script tag into your HTML. The server-first component model and the SPA-style navigation system each create their own problems, and together they reliably break naive analytics setups.

The App Router client boundary problem

Next.js App Router renders server components by default, which means any code that touches browser APIs like window or document will throw a runtime error if it executes on the server. Analytics scripts almost always depend on those browser globals. To use them safely, you must place them inside a Client Component, one marked with the 'use client' directive at the top of the file. This creates a client boundary: everything inside that component (and its children) runs in the browser, not on the server. Without this boundary, your analytics initialisation crashes before it ever fires a single pageview.

Hydration adds another layer of complexity. Because Next.js streams HTML to the browser and then hydrates it with React, the document <head> is not always a reliable injection point. A thin, dedicated Client Component wrapper is a cleaner and more predictable approach.

SPA navigation and missing pageview events

SPA navigation in Next.js does not trigger full page loads or native browser pageview events, so any analytics script that listens for a traditional page load will simply miss every route change after the first one. Users can click through five pages and your dashboard shows one visit. A single visit. That is all you get.

The next/script component helps with load timing. It offers three strategies: beforeInteractive, afterInteractive (the default), and lazyOnload. For analytics, beforeInteractive is the wrong choice because it blocks hydration and damages your Core Web Vitals scores, particularly LCP and CLS. The afterInteractive or lazyOnload strategies are far safer. Even so, script load timing does not solve the missing-pageview problem on its own. Your analytics tool still needs to listen for History API events like pushState and popstate to detect client-side route changes reliably.

Which Analytics Tool Should You Use With Next.js?

For GDPR-compliant, Cookieless tracking without a consent banner, Litlyx is our recommended choice throughout this tutorial. It collects no personal data, writes nothing to browser storage, and its EU hosting means your data never crosses into a third-party jurisdiction you did not choose.

That said, the three most common options each carry a distinct trade-off worth understanding before you commit.

Vercel Analytics is the path of least resistance if your project already lives on Vercel. Setup is minimal, and pageview data appears in your Vercel dashboard almost instantly. The catch is that Vercel Analytics is priced per event and has limited custom event tracking capabilities, which makes it expensive as traffic grows and awkward when you need product-level event data.

Google Analytics 4 via `@next/third-parties` is familiar to most marketing teams. The `@next/third-parties` library provides a `GoogleAnalytics` component that wraps the standard gtag.js tag in a Next.js-friendly way. The problem is that GA4 stores browser identifiers and processes IP addresses, so it triggers GDPR and ePrivacy Directive obligations. You will need a consent management platform, a privacy policy update, and you will almost certainly see a measurable drop in data completeness once users start declining.

Litlyx sidesteps all of that. Because Litlyx collects no personal data and sets no cookies, it sits outside the scope of personal data processing under GDPR entirely. There is one npm package, one initialisation call, and the SDK handles SPA route detection automatically. It also works in server-side contexts, so teams using Next.js API routes or server actions can fire events without any client boundary gymnastics.

The structural patterns we cover in the steps below (client boundaries, layout-level providers, custom event calls) are not exclusive to Litlyx. If your team prefers a different Privacy-first analytics tool, the same architecture applies. We use Litlyx here because it offers the cleanest path to data-driven decisions without the compliance overhead.

Step 1: Create Your Litlyx Project and Get Your Project ID

Getting started with Litlyx is genuinely fast. The whole onboarding takes around 30 seconds from signup to your first data point. Head to litlyx.com, create a free account, and you will land directly on the project creation screen. Give your project a name that matches your Next.js app, then confirm.

Once the project is created, the dashboard immediately surfaces your Project ID. This single string is the only credential you need. There are no API keys to rotate, no measurement IDs to hunt down, and no tag manager containers to configure. Copy the Project ID and keep it somewhere handy, because it is the one value you will pass to the SDK in the next steps.

The Project ID appears at the top of the project settings panel, clearly labeled. You can also find it in the onboarding snippet that Litlyx displays the first time you open a new project. Either way, it is hard to miss.

This simplicity is intentional. Because Litlyx collects no personal data and sets no cookies, there is no consent configuration to wrestle with, no data-processing agreements buried in a setup wizard, and no compliance layer standing between you and user-friendly insights. One ID, and you are ready to install the package.

Step 2: Install the Litlyx Package in Your Next.js Project

Installing Litlyx takes less than a minute. The npm install litlyx-js command is all you need, with no additional peer dependencies required. Pick whichever package manager your project already uses:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Once that completes, open package.json and confirm litlyx-js appears in your dependencies block. If it shows up there, you are ready to move forward.

One detail worth calling out: the package is isomorphic. That means it runs correctly in both client and server contexts, which matters a great deal in a Next.js App Router project where components can execute on either side. You will not need separate builds or conditional imports to keep things working. As the Litlyx GitHub repo confirms, initialising with Lit.init('workspace_id') automatically handles page visit tracking, real-time users, and unique visitors once the package is in place.

This single package is the only dependency the Cookieless tracking setup requires. No tag manager containers, no additional SDKs, no configuration files to generate.

Step 3: Add the Analytics Provider to Your Root Layout

Open app/layout.tsx and add a thin wrapper component that initialises Litlyx with your Project ID. Because this file sits at the root of the App Router tree, any component you place inside <body> here will render on every route automatically, giving you full-coverage pageview tracking from a single insertion point.

Why the Provider Must Be a Client Component

Next.js App Router renders server components by default, which means any code that references browser APIs like window or document will throw a runtime error if it executes on the server. Litlyx initialisation reads browser context to capture page paths and referrer data, so it must run client-side.

The solution is the 'use client' directive. Adding it to the top of a component file marks a boundary in the component tree: that component and everything it imports runs only in the browser. Crucially, you do not need to mark your entire layout.tsx as a client component. The most performant pattern is to create a separate component that confines the client boundary exclusively to that one file, leaving the rest of your layout as a lean server component.

Code: LitlyxProvider and Root Layout

Create a new file at app/LitlyxProvider.tsx:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Then open app/layout.tsx and place the provider inside <body>:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Replace YOUR_PROJECT_ID with the ID you copied from the Litlyx dashboard in Step 1. The useEffect hook fires after hydration, which is exactly when browser APIs become available. The component returns null so it adds zero visible markup to your page. Because the provider sits above {children} in the tree, it initialises before any page-level components mount, ensuring no pageview is missed. This pattern keeps your analytics setup tidy, isolated, and easy to remove or swap without touching any other part of the layout.

Step 4: Does Automatic Pageview Tracking Work With App Router Navigation?

Yes, Litlyx handles route-change detection automatically once the SDK is initialised in the root layout. You do not need to write any additional code to capture navigation events between pages. The SDK takes care of it from the moment the provider mounts.

How the SDK Catches SPA Navigation

SPA navigation in Next.js does not trigger full page loads or native browser pageview events, which is the core challenge for any analytics tool in an App Router project. Instead of relying on those native events, Litlyx listens to the browser's History API, specifically the pushState and popstate events. Every time Next.js pushes a new route onto the history stack, the SDK intercepts that change and fires a pageview automatically.

This approach mirrors how other privacy-focused analytics tools handle SPA navigation. Privacy-focused analytics tools are designed to automatically detect client-side route changes by listening to the History API, which makes them a natural fit for Next.js App Router projects without any extra configuration on your part.

Google Analytics 4 works differently. Because GA4 was built around traditional full-page loads, it requires manual pageview calls on every route change in Next.js. Teams using GA4 typically wire up usePathname and a useEffect to send those calls themselves, adding code complexity and maintenance overhead. With Litlyx, that entire layer is simply not needed.

What Data Gets Collected

Each automatic pageview records three things: the page path, the referrer, and a broad user agent category (such as desktop or mobile). That is it. No IP addresses, no personal identifiers, no fingerprinting. The result is genuine Cookieless tracking that gives you the user-friendly insights you need while keeping your implementation fully GDPR-compliant by design.

Step 5: Track Custom Events for Data-Driven Decisions

Look, custom event tracking is where analytics becomes genuinely useful for making data-driven decisions. You import the Lit object from litlyx-js inside any Client Component, call `Lit.event('event_name')` with an optional metadata object, and the event appears in your dashboard within seconds.

Pageview data tells you where people go. Custom events tell you what they actually do. Signups, purchases, form submissions, video plays: these are the actions that matter to your business, and they are all trackable with a single function call.

Code: Event Tracking in a Client Component

Here is a worked example covering two common cases: a signup button click and a form submission.

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

The 'use client' directive is required here because event handlers like onClick and onSubmit are browser-only interactions. The rest of your component tree stays server-rendered.

Once events fire, they surface immediately in the Litlyx dashboard under the Events panel. You can filter by event name, view counts over time, and inspect any metadata you attached. These are the kind of user-friendly insights that let you act on real behaviour rather than guesswork.

Critically, Litlyx collects no personal data and sets no cookies, so every event call you make stays fully GDPR-compliant by design. No IP addresses, no fingerprints, no identifiers are stored alongside your event data. Your implementation stays clean without any extra configuration on your part.

Step 6: Verify Everything Is Working in the Litlyx Dashboard

Once your provider is in place and custom events are wired up, confirming the integration is straightforward. Run your dev server with npm run dev, then open a few pages in the browser to generate some traffic. Within seconds, you should see data appearing in the real-time view of your Litlyx dashboard.

Start by navigating between two or three routes in your app. Because Litlyx initialises automatically and tracks page visits, real-time users, and unique visitors without any extra configuration, each route change registers as a pageview almost instantly. No manual calls, no helper functions. Just live data.

Next, trigger one of the custom events you set up in Step 5, such as clicking your signup button. Switch over to the Events panel in the dashboard and confirm the event name appears with the correct metadata attached. If you see it there, your full pipeline is healthy.

Here is a quick summary of what the dashboard surfaces at a glance:

  • Sessions and pageviews updated in real time
  • Top pages ranked by visit count
  • Custom events with names and optional metadata
  • Referrers showing where your visitors are coming from

Because Litlyx collects no personal data and sets no cookies, every number you see represents genuine behavioural signal rather than inflated or sampled figures. That is the foundation for making real data-driven decisions, without the noise that plagues heavier analytics setups.

How Do You Keep Analytics GDPR-Compliant Without a Consent Banner?

Because Litlyx collects no personal data and sets no cookies, no consent banner is legally required under GDPR or the ePrivacy Directive. That single architectural decision removes one of the biggest friction points in modern web analytics.

The legal reasoning is straightforward. GDPR Article 6 requires a lawful processing ground only when personal data is being processed. If your analytics tool never touches a name, email address, IP address, or any other identifier that could single out an individual, Article 6 simply does not apply. The ePrivacy Directive similarly restricts the storage of information on a user's device, but again, only when that storage actually occurs. Cookieless tracking that writes nothing to the browser falls entirely outside that restriction.

Google Analytics 4 sits on the opposite end of this spectrum. It stores browser identifiers, processes IP addresses, and sends data to US-based servers, which means GA4 implementations require explicit consent management under both GDPR and ePrivacy. Teams using GA4 typically see meaningful drops in measured traffic because a portion of visitors decline before any data fires.

Litlyx is EU-hosted and fully GDPR-compliant, which adds another layer of comfort for European teams. Because the data never leaves EU infrastructure, there are no third-country transfer concerns under GDPR Chapter V. You do not need Standard Contractual Clauses or adequacy decisions to justify the data flow.

The practical result is a clean user experience. No banner, no opt-out flow, no compliance overhead on your legal team's desk. Privacy-first analytics means you capture accurate, unfiltered data while your users browse without interruption. For teams making data-driven decisions, that accuracy matters just as much as the compliance benefit itself., -

Frequently asked questions

Does Litlyx work with the Next.js Pages Router as well as the App Router?

Yes, Litlyx works with both Next.js App Router and Pages Router. However, the integration approach differs slightly. With App Router, you use a Client Component wrapper to handle the `'use client'` boundary requirement. With Pages Router, you can use `next/script` with `afterInteractive` strategy in `_document.js` or `_app.js`. Both approaches require listening to History API events (`pushState`, `popstate`) to track SPA navigation correctly, since neither router triggers native pageview events on client-side route changes.

Can I use Litlyx analytics on a self-hosted Next.js app (not Vercel)?

Absolutely. Litlyx is platform-agnostic and works on any hosting provider—Vercel, Netlify, AWS, self-hosted servers, or anywhere else. Since Litlyx is a third-party analytics service, your Next.js app simply sends events to Litlyx's servers via HTTP requests. The integration method (Client Component, custom hooks, server-side tracking) remains the same regardless of where your app is deployed. No Vercel-specific features are required.

Does adding analytics to Next.js require a consent banner under GDPR?

Not with Litlyx. Because Litlyx collects no personal data, sets no cookies, and stores no browser identifiers, it falls outside GDPR's personal data processing scope entirely. You do not need a consent banner or cookie notice. However, if you use Google Analytics 4 or similar tools that process IP addresses and set cookies, you must implement a consent management platform and update your privacy policy. Always verify your specific jurisdiction's requirements.

How is Litlyx different from Vercel Analytics for Next.js projects?

Vercel Analytics is tightly integrated with Vercel's dashboard and requires minimal setup, but it's priced per event and has limited custom event tracking, making it expensive at scale. Litlyx is privacy-first, GDPR-compliant, cookieless, and EU-hosted. It offers unlimited custom events, no personal data collection, and works on any hosting platform—not just Vercel. Vercel Analytics is simpler if you're already on Vercel; Litlyx offers more flexibility and privacy guarantees.

Will analytics scripts affect my Next.js Core Web Vitals scores?

Only if you load them incorrectly. Using `next/script` with `beforeInteractive` strategy blocks hydration and damages LCP and CLS scores—avoid this for analytics. Instead, use `afterInteractive` or `lazyOnload` strategies, which load scripts after the page is interactive. Litlyx's SDK is lightweight and designed to minimize performance impact. Proper implementation (Client Component boundaries, deferred loading) ensures analytics do not harm your Core Web Vitals.

Can I track custom events server-side in Next.js API routes with Litlyx?

Yes. Litlyx supports server-side event tracking via HTTP POST requests. In Next.js API routes or server actions, you can send events directly to Litlyx's endpoint without client-side limitations. This is useful for tracking backend events (form submissions, database updates, payments) that users never see. You'll need your Litlyx project ID and can use `fetch()` or any HTTP client to POST event data from your server.

How do I test that pageview tracking is firing correctly in development?

Open your browser's Network tab (DevTools → Network) and filter for requests to Litlyx's domain. Navigate between pages and watch for pageview events in the network log. You should see a new request for each route change. Alternatively, log into your Litlyx dashboard and check the real-time events feed—pageviews should appear within seconds. In development, ensure your Litlyx project ID is correctly set and that your Client Component is properly marked with `'use client'`.

Why does Next.js App Router require a Client Component for analytics?

Next.js App Router renders server components by default. Analytics libraries need access to browser APIs like `window` and `document`, which don't exist on the server. Wrapping your analytics code in a Client Component (marked with `'use client'`) creates a boundary that ensures the code runs only in the browser, preventing runtime errors. This is a fundamental requirement of the App Router's server-first architecture.

What happens if I use a standard script tag for analytics in Next.js?

Standard script tags break in Next.js App Router for two reasons: (1) they execute on the server and crash when accessing `window` or `document`, and (2) SPA navigation doesn't trigger native pageview events, so you only capture the first page load. After that, route changes are invisible to your analytics. You must use a Client Component and listen to History API events (`pushState`, `popstate`) to track all navigation correctly.

Do I need a privacy policy if I use Litlyx?

You should still have a privacy policy that mentions analytics, but Litlyx's privacy-first approach simplifies it significantly. Since Litlyx collects no personal data and sets no cookies, you don't need detailed consent language or cookie disclosures. Simply state that you use analytics to understand user behavior, with no personal data collected. Check your local regulations—GDPR, CCPA, and others may have specific privacy policy requirements regardless of the tool.

Can I track user behavior across multiple pages in a Next.js SPA without a user ID?

Yes. Litlyx uses anonymous session tracking by default—it groups pageviews and events into sessions without collecting personal data or setting persistent cookies. You can track user journeys (page A → page B → page C) within a single session without identifying who the user is. If you need cross-session tracking, you can optionally pass a custom anonymous identifier, but Litlyx never requires personal data like email or IP addresses.