The App Router is the default architecture in Next.js 13 and later. To implement Cookiebot, use the next/script component with strategy="beforeInteractive" in your root layout file (app/layout.tsx or app/layout.js).
Open app/layout.tsx and add the Cookiebot script as shown below, replacing the zeroes with the Domain ID from the Your scripts tab in the Cookiebot Manager:
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Script
id="cookiebot"
src="https://consent.cookiebot.com/uc.js"
data-cbid="00000000-0000-0000-0000-000000000000"
data-blockingmode="auto"
strategy="beforeInteractive"
/>
{children}
</body>
</html>
);
}id="cookiebot" attribute is required by Next.js when using strategy="beforeInteractive". Without it, Next.js will throw an error.The following attributes are required for a correct implementation:
| Attribute | Value | Purpose |
|---|---|---|
strategy | "beforeInteractive" | Loads Cookiebot before React hydrates the page, preventing the consent banner from flashing and disappearing on first load. |
data-blockingmode | "auto" | Enables the Cookiebot autoblocker, which prevents third-party scripts from setting cookies before the user has consented. |
id | "cookiebot" | Required by Next.js for all beforeInteractive scripts. |
<Script> component inside a manually written <head> tag. Next.js manages the <head> element automatically in the App Router, and wrapping the script in an explicit <head> causes a hydration mismatch that prevents the consent banner from displaying correctly. Place the <Script> component directly inside <body> as shown above — Next.js will hoist it to the correct position automatically.app/layout.tsx file only. Placing it in a nested layout or a route group layout will not work — strategy="beforeInteractive" is only applied correctly from the root layout, and placing it elsewhere will cause the same banner flash as an incorrect strategy.
Implementing Cookiebot CMP in a Next.js site (Pages Router)
If your project uses the Pages Router (pages/ directory, used in Next.js 12 and earlier, or alongside the App Router), add the Cookiebot script to your custom _document file.
Create or open pages/_document.tsx and add the Cookiebot script as the first element inside <Head>:
import { Html, Head, Main, NextScript } from 'next/document';
export default function Document() {
return (
<Html lang="en">
<Head>
<script
id="Cookiebot"
src="https://consent.cookiebot.com/uc.js"
data-cbid="00000000-0000-0000-0000-000000000000"
data-blockingmode="auto"
type="text/javascript"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}<script> tag inside _document.tsx — do not use the next/script component here, as it is not supported inside _document.
Fixing the consent banner flash issue in Next.js
A common issue when integrating Cookiebot with Next.js is the consent banner briefly appearing and then disappearing on the first load, particularly in Incognito mode. This happens when Cookiebot loads after React has hydrated the page.
The most frequent causes are:
- Using a plain
<script>tag inapp/layout.tsxinstead of thenext/scriptcomponent withstrategy="beforeInteractive". - Using
next/scriptwithstrategy="afterInteractive"orstrategy="lazyOnload"— both load Cookiebot after hydration. - Placing the
next/scriptcomponent in a nested layout or route group instead of the rootapp/layout.tsx. - Adding
asyncordeferattributes to the script tag. These conflict withstrategy="beforeInteractive"and cause Cookiebot to initialise too late.
The implementation shown in the App Router section above addresses all of these. If the banner flash persists after following those steps, verify that the script is not being included more than once — for example, in both the root layout and a nested layout.
Blocking third-party scripts until consent is given
With data-blockingmode="auto" enabled, the Cookiebot autoblocker intercepts third-party scripts and prevents them from executing until the user has given consent. In Next.js, the autoblocker works correctly with scripts loaded via next/script using the following strategies:
strategy="afterInteractive"(default)strategy="lazyOnload"
Scripts loaded with strategy="beforeInteractive" run before the autoblocker initialises and will not be blocked — only use this strategy for the Cookiebot script itself.
Example of a correctly blocked Google Analytics script in Next.js:
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"
strategy="afterInteractive"
/>The autoblocker will intercept this script and delay its execution until the user has accepted statistics cookies.
Showing your cookie declaration on a Next.js page
To embed your full cookie declaration on a Privacy Policy or dedicated cookies page, add the cookie declaration script to the page where you want it to appear.
In the App Router, create a Client Component and use next/script to embed the declaration:
'use client';
import Script from 'next/script';
export default function CookieDeclaration() {
return (
<>
<Script
id="cookie-declaration"
src="https://consent.cookiebot.com/00000000-0000-0000-0000-000000000000/cd.js"
strategy="afterInteractive"
/>
<div id="CookieDeclaration" />
</>
);
}Replace the zeroes with your Domain ID. Import and render this component on the page where the declaration should appear.
strategy="afterInteractive" (or the async attribute in the Pages Router). Unlike the main Cookiebot script, the declaration does not need to load before hydration.
Testing on localhost
By default, Cookiebot only activates on the domain registered in your account. To test your integration on a local development environment, add a domain alias for localhost in the Cookiebot Manager:
- Go to Cookiebot Manager → Domains & Aliases.
- Select your domain and click + Add Domain Alias.
- Add
localhostandlocalhost:3000as aliases (without thehttp://prefix). - Go to Configuration and set the target to All Visitors so the banner appears regardless of the visitor's location.
When the domain alias is active, the consent banner will display a TEST watermark to indicate it is running in a non-production environment. If you see the TEST watermark on your production site, make sure your production domain is not listed as an alias.
Comments
0 comments
Please sign in to leave a comment.