> Make your Next.js app GDPR compliant: block trackers before consent, App Router setup, SPA navigation, Consent Mode v2 and server-side checks.
>
> Canonical: https://www.flowconsent.com/en/blog/nextjs-cookies-gdpr-compliance-guide

[Platform guides](https://www.flowconsent.com/en/blog?category=platforms)

# Next.js cookie consent and GDPR: the complete compliance guide

Published 13 July 2026 · Updated 2 October 2026 · 9 min read

In short

How to collect valid cookie consent in a Next.js app, from App Router installation and SPA navigation to Google Consent Mode v2 and server-side consent checks.

## TL;DR

A Next.js site that loads Google Analytics, the Meta Pixel or any other tracker must collect visitor consent before those scripts run, as required by the GDPR and the ePrivacy rules. Showing a banner is not enough: non-essential scripts must stay blocked until the visitor explicitly agrees, Google Consent Mode v2 signals must start in the `denied` state, the choice must be respected on every client-side navigation, and you need proof of each consent. This guide covers the GDPR requirements, the Next.js specifics (App Router, Server Components, SPA navigation, SSR) and a step-by-step implementation.

## Why cookie compliance matters for a Next.js app

Next.js is a React framework widely used for marketing sites, e-commerce stores, SaaS products and editorial platforms, often deployed on Vercel or Netlify. Its flexibility is also its main compliance risk: developers routinely add Google Analytics 4, Google Tag Manager, the Meta Pixel, Hotjar, Intercom and more, each of which sets cookies or similar trackers that require prior consent.

The most common mistake is loading these scripts in `_app.tsx`, `app/layout.tsx` or a shared Layout component with no consent check at all. The pattern is extremely widespread and amounts to a clear GDPR violation: trackers fire on the first page view, before the visitor has had any chance to choose.

The consequences are concrete. European regulators have fined major websites tens of millions of euros over cookie consent, complaints from digital rights organisations such as noyb are frequent, and a banner that does not do what it says damages user trust.

## What the GDPR requires for cookies in Next.js

The GDPR, together with the ePrivacy Directive, sets three core obligations for non-essential cookies: inform users clearly, collect their consent before activating trackers, and let them withdraw that consent as easily as they gave it.

### Which cookies require consent?

Most third-party tools integrated into a Next.js app require consent:

- Analytics: Google Analytics 4, and Matomo or Plausible when not configured for an exemption
- Advertising and marketing: Meta Pixel, LinkedIn Insight Tag, Google Ads, TikTok Pixel
- User experience: Hotjar, FullStory, LogRocket, Microsoft Clarity
- Support and chat: Intercom, Drift, HubSpot Chat

Cookies that are strictly necessary for the application to work (session, authentication, shopping cart) are exempt. Note that `localStorage` and `sessionStorage` follow the same rules as cookies: a tracker that writes to storage needs consent too.

### The three core obligations

- **Inform**: describe which cookies are used, why and by whom, before any of them is set.
- **Collect valid consent**: freely given, specific, informed and unambiguous. No pre-ticked boxes, no implied consent through scrolling, and a Reject option as easy to use as Accept.
- **Respect the choice**: do not load rejected scripts, allow withdrawal at any time, and ask again after a reasonable period. Trackers should not live longer than 13 months (see our guide to the [13-month cookie retention rule](https://www.flowconsent.com/en/blog/cookie-retention-duration-gdpr-13-months)).

## The Next.js specifics

### Server Components vs Client Components

With the App Router (Next.js 13 and later), the boundary between Server and Client Components matters for consent:

- **Server Components** run on the server and have no access to `document.cookie` or `localStorage`. They can only learn about consent through the HTTP cookie sent with the request.
- **Client Components** (marked `'use client'`) run in the browser and can react to consent events.
- **Middleware and Route Handlers** can read the consent cookie to adapt rendering or server-side processing.

### Client-side navigation

A Next.js app navigates with `history.pushState`, without reloading the page. On a classic site, every page load re-runs the banner and re-blocks tracking scripts. In a single-page app, scripts injected after the first page would not be re-checked unless your consent tool hooks into client-side navigation.

### The script loading problem

The `next/script` component offers several loading strategies. With `strategy="afterInteractive"`, a script loads as soon as the page becomes interactive, before any click on the banner. Without a consent mechanism in front of it, GA4 or GTM fires before the banner even appears. This is the single most common violation in Next.js applications.

## Two ways to manage consent

### Option 1: use a CMP (recommended)

A Consent Management Platform such as FlowConsent handles banner display, consent collection, prior blocking of third-party scripts, Google Consent Mode v2 signals and proof of consent. Translations and regulatory changes are maintained for you.

### Option 2: build it yourself

A homemade banner is feasible with a React component and a global Context or store, but the list of things to get right is long:

- blocking every non-essential script, including those injected by GTM or third-party embeds
- sending Consent Mode v2 defaults before any Google tag
- re-checking consent on client-side navigation
- storing proof of consent (timestamp, banner version, choice per category) server-side
- renewing consent and handling withdrawal
- following every regulatory update yourself

## Installing FlowConsent in Next.js, step by step

The FlowConsent banner is a single self-contained script, with no npm package to install for the browser side. The exact snippet for your project, with your deployment URL and license code, is generated in **Builder → Deployment → Integration**, where a **Next.js** tab is available. The full procedure is in the [Next.js and React SPA integration guide](https://www.flowconsent.com/en/doc/nextjs-integration). For a React app without Next.js (Vite, Create React App, React Router), follow the [React installation guide](https://www.flowconsent.com/en/doc/install-react) instead.

### Step 1: add the script

- **App Router**: in `app/layout.tsx`, add the FlowConsent script with `<Script strategy="beforeInteractive">`. This strategy makes Next.js load it before hydration, so prior blocking is in place before any tracker fires.
- **Pages Router**: in `pages/_document.tsx`, put the FlowConsent `<script>` first inside `<Head>`.

The integration snippet also includes an inline Google Consent Mode stub that registers `denied` defaults; keep it before the loader. Do not load FlowConsent from a React component or a `useEffect`: by the time that code runs, other scripts will already have fired.

### Step 2: enable SPA Mode

In the Builder, open the **Settings** tab, turn on **SPA Mode** and redeploy the banner. FlowConsent then intercepts `history.pushState` and `history.replaceState`, listens for `popstate`, and re-blocks uncovered tracking scripts on every navigation. It also emits a `flowconsent:navigation` event you can listen to.

### Step 3: let FlowConsent manage tracking scripts

Do not load Google Analytics, the Meta Pixel or similar tools with `next/script`. Declare them in **Builder → Services** instead, and the banner injects them only once the matching category (analytics, marketing, preferences) is accepted. For embeds such as YouTube iframes, a `data-service` attribute lets the banner gate them.

The same applies to `@next/third-parties` (Next.js 14 and later): its `GoogleAnalytics` component loads GA4 through `next/script`, outside your consent tool's control. If you want FlowConsent to handle GA4, configure the service in the Builder rather than through this package.

## Google Consent Mode v2 in Next.js

Google Consent Mode v2 has been required since March 2024 for advertisers who want to keep using Google Ads audience and measurement features for users in the European Economic Area. It sends four signals to Google: `analytics_storage`, `ad_storage`, `ad_user_data` and `ad_personalization`.

FlowConsent implements it out of the box, as detailed in the [Google Consent Mode guide](https://www.flowconsent.com/en/doc/google-consent-mode):

- an inline stub registers `denied` defaults for all four signals before any Google tag loads
- `wait_for_update: 500` gives the banner time to apply a returning visitor's stored choice
- once the visitor chooses, the banner sends `gtag('consent', 'update', …)`
- after a refusal, Google tags only send cookieless pings (`gcs=G100`), which respect the refusal

Whether you use GTM or gtag.js directly, the rule is the same: the consent defaults must be in place before any Google tag initialises. For the full method, see our [Google Consent Mode v2 implementation guide](https://www.flowconsent.com/en/blog/google-consent-mode-v2-implementation-guide).

## Reading consent on the server

Some processing starts server-side: GA4 Measurement Protocol events, CRM sync, attribution logic in a Route Handler, personalised rendering in a Server Component. The banner cannot block these, so your code must check consent itself.

The `@flowconsent/server-sdk` package reads the first-party cookie set by the banner and returns a typed decision. It has no dependencies and runs on the edge (Vercel, Cloudflare Workers) as well as on Node 18 and later, which makes it usable in Middleware, Route Handlers and Server Components. The decision is **denied by default** when the cookie is missing, unreadable or stale, and `decision.can('analytics')` or `decision.can('google-analytics')` tells you whether a category or a service is allowed.

## Reacting to consent in your React code

For logic that lives in Client Components, FlowConsent dispatches a `flowconsent:consent` event whose `detail.preferences` object contains the visitor's choice per category. A small hook that subscribes to it lets you:

- initialise your own analytics only when `preferences.analytics` is true
- load components that depend on a tracker through `next/dynamic` only after consent
- update the UI when a visitor changes their mind

## Internationalisation

Next.js handles i18n routing natively, and your banner should speak the same language as the page. In FlowConsent, banner texts are translated in the **Translations** tab, and the detection method is set in **Information**. The number of languages per banner depends on the plan: 2 on Free, 5 on Pro, custom on Enterprise.

## Performance and Core Web Vitals

Consent management should not hurt your Core Web Vitals:

- reserve `strategy="beforeInteractive"` for the consent script only, never for the blocked trackers
- blocked third-party scripts use no bandwidth before consent, which lightens the first page load
- check the Lighthouse score before and after installing the banner

## Common mistakes in Next.js cookie compliance

**Loading GA4 or GTM without a consent check.** A `next/script` tag with `afterInteractive` runs before any click on the banner. Let the CMP inject trackers instead.

**Loading the CMP too late.** Injecting the banner from a component or a `useEffect` means trackers already in the page have fired by the time it starts.

**Forgetting client-side navigation.** Without SPA Mode, scripts added after the first page are not re-blocked on later routes.

**Not blocking the Meta Pixel.** It sets advertising cookies and must depend on the marketing category. Our [Meta Pixel GDPR guide](https://www.flowconsent.com/en/blog/meta-pixel-cookies-gdpr-compliance) covers the details.

**Pre-ticked boxes or passive consent.** A banner with Analytics pre-checked invalidates consent. Every non-essential category must start unchecked.

**Confusing stored state with proof.** A cookie or `localStorage` value remembers the choice in one browser, but it is not proof. Proof is a server-side record with a timestamp, banner version and choice per category (see [what to store as proof of consent](https://www.flowconsent.com/en/blog/proof-of-cookie-consent-what-to-store)).

**Never asking again.** Consent should be renewed periodically, and tracker lifetimes must not exceed 13 months.

**No way to withdraw.** Visitors must be able to reopen their preferences at any time, via a footer link or a floating button.

## Testing your implementation

1. Open the live site in a private window: the banner appears on the first page.
2. In the DevTools **Network** and **Application** tabs, check that no tracking request goes out and no non-essential cookie is set before **Accept**, including after several route changes.
3. Use Google Tag Assistant to confirm that Consent Mode starts in `denied` and switches to `granted` only after acceptance.
4. Run the [setup wizard](https://www.flowconsent.com/en/doc/setup-wizard): it checks on your live page that the stub and loader are present, in the right order.
5. Finish with a refusal scan from the **Compliance** tab: it loads your pages in a real browser, refuses consent and lists anything that still fires ([compliance verification](https://www.flowconsent.com/en/doc/compliance-verification)).

## Next.js cookie compliance checklist

- Audit every third-party script (`next/script`, GTM, direct imports, `@next/third-parties`). Our [cookie audit guide](https://www.flowconsent.com/en/blog/website-cookie-audit-complete-guide) details the method.
- Categorise each cookie: strictly necessary, preferences, analytics, marketing.
- Add the consent script in `app/layout.tsx` with `beforeInteractive`, or first in `<Head>` of `pages/_document.tsx`.
- Enable SPA Mode and redeploy the banner.
- Declare trackers in the CMP rather than loading them with `next/script`.
- Check that Consent Mode v2 defaults are `denied` before any Google tag.
- Gate server-side processing on a consent decision read from the request.
- Offer a Reject button as visible as Accept, with no pre-ticked boxes.
- Store proof of consent and renew it periodically.
- Provide a preferences link on every page.
- Verify in a private window, then with a refusal scan.

## Conclusion

GDPR compliance in a Next.js application comes down to one principle: no non-essential script runs before the visitor consents, on the first page and on every client-side navigation. Next.js makes trackers easy to add, so that rule needs a reliable mechanism: a consent script loaded before hydration, SPA Mode, trackers managed by the CMP and consent checked on the server too.

Start by [scanning your Next.js site with FlowConsent](https://www.flowconsent.com/en/scan) to see which trackers currently load without consent.

[Back to the blog](https://www.flowconsent.com/en/blog)

Share this article · [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.flowconsent.com%2Fen%2Fblog%2Fnextjs-cookies-gdpr-compliance-guide) · [X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.flowconsent.com%2Fen%2Fblog%2Fnextjs-cookies-gdpr-compliance-guide)

Questions

## Common questions on this topic.

Can't find your question? Write to us, we answer fast.

[Write to us](https://www.flowconsent.com/en/demo)

### Does a Next.js site need a cookie banner even if it only uses Google Analytics?

Yes. Google Analytics 4 sets audience measurement cookies that are not strictly necessary for the site to function. Under GDPR and ICO guidance, setting these cookies requires prior user consent. Using Next.js as a framework does not change this obligation.

### How do you block Google Tag Manager in Next.js before consent is given?

The most reliable approach is to load GTM conditionally based on a global consent state (React Context or store). The Next.js Script component with strategy='afterInteractive' must be made conditional: the component only mounts once the user has consented to the relevant categories. A dedicated CMP handles this logic automatically.

### Can Plausible or Matomo be used without a cookie banner in Next.js?

It is possible under certain conditions. Plausible Analytics does not set cookies by default and may qualify for a consent exemption if configured without user identification. Matomo can be exempted if IP anonymisation is enabled and data is not shared with third parties, in line with the ICO's guidance on analytics exemptions. Always verify the exact tool configuration before claiming an exemption.

### What is the maximum duration for a consent cookie in a Next.js app?

Regulators generally recommend that the cookie storing user consent choices should not exceed 13 months. Beyond that, consent is considered stale and must be re-collected. To remain compliant, your application should trigger a consent renewal prompt no later than 6 to 13 months after the last consent event.

Read next

## Keep reading.

[All articles](https://www.flowconsent.com/en/blog)

[Best practices · 2 March 2026](https://www.flowconsent.com/en/blog/cookie-banner-gdpr-compliance-guide)

### [Cookie banner: the complete GDPR compliance guide (2026)](https://www.flowconsent.com/en/blog/cookie-banner-gdpr-compliance-guide)

[Everything a GDPR-compliant cookie banner needs: the legal basis, what it must show, design rules against dark patterns, a step-by-step setup and a final checklist.](https://www.flowconsent.com/en/blog/cookie-banner-gdpr-compliance-guide)

[Read the article ](https://www.flowconsent.com/en/blog/cookie-banner-gdpr-compliance-guide)·

[Marketing tools · 7 April 2026](https://www.flowconsent.com/en/blog/meta-pixel-cookies-gdpr-compliance)

### [Meta Pixel and GDPR: the complete guide to cookies and consent](https://www.flowconsent.com/en/blog/meta-pixel-cookies-gdpr-compliance)

[The Meta Pixel sets advertising cookies that require prior consent in Europe. Here is how to block it until consent, handle the Conversions API and stay GDPR compliant.](https://www.flowconsent.com/en/blog/meta-pixel-cookies-gdpr-compliance)

[Read the article ](https://www.flowconsent.com/en/blog/meta-pixel-cookies-gdpr-compliance)·

[Marketing tools · 7 May 2026](https://www.flowconsent.com/en/blog/linkedin-pixel-cookies-gdpr-compliance)

### [LinkedIn Pixel and GDPR: cookie compliance guide](https://www.flowconsent.com/en/blog/linkedin-pixel-cookies-gdpr-compliance)

[The LinkedIn Insight Tag sets third-party advertising cookies. This guide explains why prior consent is mandatory and how to configure your site to stay GDPR compliant.](https://www.flowconsent.com/en/blog/linkedin-pixel-cookies-gdpr-compliance)

[Read the article](https://www.flowconsent.com/en/blog/linkedin-pixel-cookies-gdpr-compliance)

## Make your site compliant today.

Free up to 25,000 sessions a month. No credit card, no commitment.

[Create my banner](https://app.flowconsent.com/auth/sign-up?utm_source=flowconsent.com\&utm_medium=referral\&utm_campaign=general) · [Scan my site](https://www.flowconsent.com/en/scan)
