CookieFast

Next.js Integration

Complete guide for integrating CookieFast into your Next.js application, supporting both App Router and Pages Router.

App Router (Next.js 13+)

Root Layout Integration

Add CookieFast to your root layout (app/layout.tsx):

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<head>
<script
async
src="https://cdn.cookiefa.st/cookiefast.js"
data-api-key={process.env.NEXT_PUBLIC_COOKIEFAST_API_KEY}
/>
</head>
<body>{children}</body>
</html>
);
}

Environment Variables

.env.local:

NEXT_PUBLIC_COOKIEFAST_API_KEY=your-api-key-here

Always use the NEXT_PUBLIC_ prefix for client-side environment variables in Next.js!

Script Component (Alternative)

Use Next.js's built-in Script component:

import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Script
src="https://cdn.cookiefa.st/cookiefast.js"
data-api-key={process.env.NEXT_PUBLIC_COOKIEFAST_API_KEY}
strategy="afterInteractive"
/>
{children}
</body>
</html>
);
}

Pages Router (Next.js 12 and below)

Custom Document

Add to pages/_document.tsx:

import { Html, Head, Main, NextScript } from 'next/document';
export default function Document() {
return (
<Html lang="en">
<Head>
<script
async
src="https://cdn.cookiefa.st/cookiefast.js"
data-api-key={process.env.NEXT_PUBLIC_COOKIEFAST_API_KEY}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}

Using Script Component

In pages/_app.tsx:

import Script from 'next/script';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Script
src="https://cdn.cookiefa.st/cookiefast.js"
data-api-key={process.env.NEXT_PUBLIC_COOKIEFAST_API_KEY}
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
);
}

Client Component Hook

Create a consent hook (hooks/useCookieConsent.ts):

'use client'; // For App Router
import { useState, useEffect } from 'react';
interface CookieConsent {
analytics: boolean;
marketing: boolean;
essential: boolean;
}
export function useCookieConsent() {
const [consent, setConsent] = useState<CookieConsent | null>(null);
useEffect(() => {
const handleConsent = (event: CustomEvent<CookieConsent>) => {
setConsent(event.detail);
};
window.addEventListener('cookiefast:consent', handleConsent as EventListener);
// Check existing consent
if (window.CookieFast) {
setConsent(window.CookieFast.getConsent());
}
return () => {
window.removeEventListener('cookiefast:consent', handleConsent as EventListener);
};
}, []);
return consent;
}

Cookie Settings Component

'use client';
export function CookieSettings() {
const handleClick = () => {
if (window.CookieFast) {
window.CookieFast.showBanner();
}
};
return (
<button onClick={handleClick} className="text-sm underline">
Cookie Settings
</button>
);
}

Use in any component:

import { CookieSettings } from '@/components/CookieSettings';
export default function Footer() {
return (
<footer>
<CookieSettings />
</footer>
);
}

Google Analytics Integration

App Router

Create an analytics component (components/Analytics.tsx):

'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import { useCookieConsent } from '@/hooks/useCookieConsent';
export function Analytics() {
const pathname = usePathname();
const searchParams = useSearchParams();
const consent = useCookieConsent();
useEffect(() => {
if (consent?.analytics) {
// Initialize GA
const script = document.createElement('script');
script.src = `https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_ID}`;
script.async = true;
document.head.appendChild(script);
window.dataLayer = window.dataLayer || [];
function gtag(...args: any[]) {
window.dataLayer.push(args);
}
gtag('js', new Date());
gtag('config', process.env.NEXT_PUBLIC_GA_ID);
}
}, [consent]);
// Track page views
useEffect(() => {
if (consent?.analytics && window.gtag) {
const url = pathname + searchParams.toString();
window.gtag('event', 'page_view', {
page_path: url,
});
}
}, [pathname, searchParams, consent]);
return null;
}

Add to root layout:

import { Analytics } from '@/components/Analytics';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Analytics />
</body>
</html>
);
}

Pages Router

In pages/_app.tsx:

import { useEffect } from 'react';
import { useRouter } from 'next/router';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
const router = useRouter();
useEffect(() => {
const handleConsent = (event: CustomEvent) => {
if (event.detail.analytics) {
// Initialize Google Analytics
const script = document.createElement('script');
script.src = `https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_ID}`;
document.head.appendChild(script);
window.dataLayer = window.dataLayer || [];
function gtag(...args: any[]) {
window.dataLayer.push(args);
}
gtag('js', new Date());
gtag('config', process.env.NEXT_PUBLIC_GA_ID);
}
};
window.addEventListener('cookiefast:consent', handleConsent as EventListener);
return () => {
window.removeEventListener('cookiefast:consent', handleConsent as EventListener);
};
}, []);
// Track page views
useEffect(() => {
const handleRouteChange = (url: string) => {
if (window.gtag) {
window.gtag('event', 'page_view', {
page_path: url,
});
}
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events]);
return <Component {...pageProps} />;
}

TypeScript Definitions

Create types/cookiefast.d.ts:

interface CookieConsentDetail {
analytics: boolean;
marketing: boolean;
essential: boolean;
}
interface CookieFast {
getConsent(): CookieConsentDetail | null;
showBanner(): void;
}
interface Window {
CookieFast?: CookieFast;
dataLayer?: any[];
gtag?: (...args: any[]) => void;
}
interface WindowEventMap {
'cookiefast:consent': CustomEvent<CookieConsentDetail>;
}

Server-Side Rendering (SSR)

CookieFast works client-side only. Ensure consent checks happen in useEffect or client components:

'use client';
import { useEffect, useState } from 'react';
export function MarketingPixel() {
const [canLoad, setCanLoad] = useState(false);
useEffect(() => {
const handleConsent = (event: CustomEvent) => {
if (event.detail.marketing) {
setCanLoad(true);
}
};
window.addEventListener('cookiefast:consent', handleConsent as EventListener);
return () => {
window.removeEventListener('cookiefast:consent', handleConsent as EventListener);
};
}, []);
if (!canLoad) return null;
return (
<script
dangerouslySetInnerHTML={{
__html: `
// Your marketing pixel code
`,
}}
/>
);
}

Deployment

Vercel

Add environment variable in Vercel dashboard:

  • Key: NEXT_PUBLIC_COOKIEFAST_API_KEY
  • Value: Your API key from CookieFast dashboard

Other Platforms

Ensure environment variables are set:

NEXT_PUBLIC_COOKIEFAST_API_KEY=your-api-key-here

Next Steps