> ## Documentation Index
> Fetch the complete documentation index at: https://docs.katla.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js

> Integrate Katla cookie consent into a Next.js App Router project.

The `@katla.app/sdk/next` entry point provides a pre-configured provider for Next.js that bundles the guard script injection, consent bridge, and all React hooks into a single `"use client"` import.

## Prerequisites

* Next.js 13+ with the App Router
* `@katla.app/sdk` installed ([see SDK overview](/sdk))

## Setup

### 1. Add the provider to your root layout

Import `KatlaNextProvider` directly in your root layout. Because the provider already includes a `'use client'` directive, no wrapper file is needed — and children passed from a Server Component remain server-rendered.

```tsx theme={null}
// src/app/layout.tsx
import { KatlaNextProvider } from '@katla.app/sdk/next';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <KatlaNextProvider siteId="your-site-id">
          {children}
        </KatlaNextProvider>
      </body>
    </html>
  );
}
```

`KatlaNextProvider` includes `KatlaGuard` and `ConsentBridge` automatically. To enable Google Consent Mode, pass the `googleConsentMode` prop:

```tsx theme={null}
<KatlaNextProvider siteId="your-site-id" googleConsentMode>
  {children}
</KatlaNextProvider>
```

<Note>
  Pages and components rendered as `{children}` remain Server Components. The `'use client'` boundary only affects the provider itself, not its children.
</Note>

### KatlaNextProvider props

| Prop                | Type                 | Default                  | Description                                                                                                                            |
| ------------------- | -------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| `siteId`            | `string`             | —                        | Your site's UUID (required)                                                                                                            |
| `baseUrl`           | `string`             | `https://dist.katla.app` | Override the CDN base URL                                                                                                              |
| `locale`            | `PolicyLocale`       | —                        | Default locale for policy documents (e.g., `en-GB`, `de-DE`, `sv-SE`). When set, all policy fetches use this locale unless overridden. |
| `debug`             | `boolean`            | `false`                  | Enable console logging                                                                                                                 |
| `initialCookies`    | `CookieData \| null` | —                        | Pre-fetched cookie data. When provided, `useKatlaCookies()` skips the runtime fetch.                                                   |
| `guardScript`       | `string`             | —                        | Pre-fetched guard script content. When provided, the guard is inlined instead of fetched from the CDN.                                 |
| `guard`             | `boolean`            | `true`                   | Inject the cookie guard script that blocks non-consented cookies                                                                       |
| `consentBridge`     | `boolean`            | `true`                   | Connect `window.KatlaConsent` events to the React consent state                                                                        |
| `googleConsentMode` | `boolean`            | `false`                  | Signal consent state to Google Analytics/Ads via [Google Consent Mode v2](/google-consent-mode)                                        |

## Using hooks

Import hooks directly from `@katla.app/sdk/next`. They work the same as in the [React guide](/sdk-react) but are re-exported with the `"use client"` directive already applied.

```tsx theme={null}
'use client';

import { useKatlaCookies, useKatlaConsent } from '@katla.app/sdk/next';

export default function CookiePage() {
  const { cookies, loading, error } = useKatlaCookies();
  const { consent } = useKatlaConsent();

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      {cookies &&
        Object.entries(cookies.cookies).map(([category, list]) => (
          <div key={category}>
            <h3>{category} ({list.length})</h3>
          </div>
        ))}

      {consent && (
        <ul>
          {Object.entries(consent).map(([cat, allowed]) => (
            <li key={cat}>{cat}: {allowed ? 'Allowed' : 'Declined'}</li>
          ))}
        </ul>
      )}
    </div>
  );
}
```

Available hooks:

| Hook                  | Description                                                                                    |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| `useKatlaCookies()`   | Fetch cookie data — returns `{ cookies, loading, error }`                                      |
| `useKatlaConsent()`   | Track consent state — returns `{ consent, onChange }`                                          |
| `useKatlaClient()`    | Access the underlying `KatlaClient` instance                                                   |
| `useConsentManager()` | Combined consent state, cookie data, and actions — see [React guide](/react#useconsentmanager) |

## Components

All consent UI components are available from `@katla.app/sdk/next` and work identically to the [React versions](/react#components). They are **unstyled** and render semantic HTML with stable `katla-*` class names.

### CookieBanner

A ready-to-use consent banner with accept, reject, and per-category customization.

```tsx theme={null}
'use client';

import { CookieBanner } from '@katla.app/sdk/next';

export function ConsentBanner() {
  return (
    <CookieBanner
      title="We use cookies"
      description="Choose which categories you'd like to allow."
    />
  );
}
```

Use the `children` render prop for a fully custom UI:

```tsx theme={null}
'use client';

import { CookieBanner } from '@katla.app/sdk/next';

export function ConsentBanner() {
  return (
    <CookieBanner>
      {({ acceptAll, rejectAll, open, setOpen, saveSelection }) => (
        <div>
          <button onClick={acceptAll}>OK</button>
          <button onClick={rejectAll}>No thanks</button>
          <button onClick={() => setOpen(!open)}>Customize</button>
        </div>
      )}
    </CookieBanner>
  );
}
```

See the [CookieBanner props and class names](/react#cookiebanner) reference in the React guide.

### CookieCatalog

Displays your site's cookies grouped by category.

```tsx theme={null}
'use client';

import { useKatlaCookies, CookieCatalog } from '@katla.app/sdk/next';

export function CookieList() {
  const { cookies, loading, error } = useKatlaCookies();
  return <CookieCatalog data={cookies} loading={loading} error={error} />;
}
```

See the [CookieCatalog props and class names](/react#cookiecatalog) reference in the React guide.

## Building a consent banner

The fastest way to add a consent banner is with the `<CookieBanner>` component — it handles all the consent logic out of the box. For full control, use the `useConsentManager` hook or call `window.KatlaConsent` methods directly.

```tsx theme={null}
'use client';

import { useKatlaCookies, useKatlaConsent, COOKIE_CATEGORIES } from '@katla.app/sdk/next';

function CustomConsentBanner() {
  const { cookies } = useKatlaCookies();
  const { consent } = useKatlaConsent();

  if (consent) return null; // Already consented

  const categories = cookies
    ? Object.keys(cookies.cookies)
    : [...COOKIE_CATEGORIES];

  return (
    <div>
      <p>This site uses cookies. Choose your preferences:</p>
      <ul>
        {categories.map((cat) => (
          <li key={cat}>{cat}</li>
        ))}
      </ul>
      <button onClick={() => window.KatlaConsent?.acceptAll()}>
        Accept all
      </button>
      <button onClick={() => window.KatlaConsent?.rejectAll()}>
        Reject all
      </button>
    </div>
  );
}
```

<Note>
  `window.KatlaConsent` is provided by the guard script that `KatlaNextProvider` injects automatically.
</Note>

## Server-side rendering (SSR)

Use `getCachedCookies` from `@katla.app/sdk/next/server` to fetch cookies in a Server Component and pass them to the provider. This avoids the client-side network request while keeping data fresh on every request.

```tsx theme={null}
// src/app/layout.tsx
import { KatlaNextProvider } from '@katla.app/sdk/next';
import { getCachedCookies } from '@katla.app/sdk/next/server';

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const cookies = await getCachedCookies({ siteId: 'your-site-id' });

  return (
    <html lang="en">
      <body>
        <KatlaNextProvider siteId="your-site-id" initialCookies={cookies}>
          {children}
        </KatlaNextProvider>
      </body>
    </html>
  );
}
```

When `initialCookies` is provided, `useKatlaCookies()` returns the data immediately with `loading: false` and makes no network request.

<Note>
  `getCachedCookies` uses React's `cache()` to deduplicate requests — even if multiple Server Components call it in the same render, only one fetch is made. It is a server-only import (`@katla.app/sdk/next/server`). Don't import it in client components.
</Note>

## Static cookies (build-time)

Use the Katla CLI to fetch cookie data at build time and bundle it as static data — no runtime fetch needed. This is ideal for static sites or when you want the fastest possible page load.

### CLI approach

Use the Katla CLI in your build pipeline:

```json theme={null}
{
  "scripts": {
    "prebuild": "katla pull your-site-id",
    "build": "next build"
  }
}
```

```tsx theme={null}
// src/app/layout.tsx
import { KatlaNextProvider } from '@katla.app/sdk/next';
import { getStaticGuardScript } from '@katla.app/sdk/next/server';
import cookies from './.katla/cookies.json';

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const guardScript = await getStaticGuardScript();

  return (
    <html lang="en">
      <body>
        <KatlaNextProvider siteId="your-site-id" initialCookies={cookies} guardScript={guardScript}>
          {children}
        </KatlaNextProvider>
      </body>
    </html>
  );
}
```

When `initialCookies` is provided, `useKatlaCookies()` returns the data immediately with `loading: false` and makes no network request. `getStaticGuardScript()` reads the guard script from the `.katla/` directory so it can be inlined instead of fetched from the CDN.

## Debug mode

Pass `debug` to `KatlaNextProvider` to enable console logging:

```tsx theme={null}
<KatlaNextProvider siteId="your-site-id" debug>
  {children}
</KatlaNextProvider>
```

## Full example

A complete Next.js App Router setup with a cookie catalog and consent banner:

<Tabs>
  <Tab title="layout.tsx">
    ```tsx theme={null}
    // src/app/layout.tsx
    import { KatlaNextProvider } from '@katla.app/sdk/next';

    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <KatlaNextProvider siteId="your-site-id" debug>
              {children}
            </KatlaNextProvider>
          </body>
        </html>
      );
    }
    ```
  </Tab>

  <Tab title="page.tsx">
    ```tsx theme={null}
    // src/app/page.tsx
    'use client';

    import { useKatlaCookies, CookieBanner, CookieCatalog } from '@katla.app/sdk/next';

    export default function Home() {
      const { cookies, loading, error } = useKatlaCookies();

      return (
        <div>
          <h1>Cookie consent</h1>
          <CookieCatalog data={cookies} loading={loading} error={error} />
          <CookieBanner />
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

## Examples

<CardGroup cols={2}>
  <Card title="Dynamic SSR" icon="github" href="https://github.com/katla-app/examples/tree/main/nextjs-sdk-dynamic">
    Next.js App Router with server-side cookie fetching via `getCachedCookies`.
  </Card>

  <Card title="Build-time static" icon="github" href="https://github.com/katla-app/examples/tree/main/nextjs-sdk-static">
    Next.js App Router using `katla pull` for build-time cookie data.
  </Card>
</CardGroup>
