Next.js
Client-side initialization
When to initialize in the browser
This setup has the fewest files. The browser calls your Inth backend's /init
after the page loads, so the server does no consent work and every page can be
static. The HTML is the same for every visitor, and the banner appears after
hydration.
Use it when you do not need the banner in the server HTML and do not want a
consent route. For a server app, the App Router
and Pages Router guides resolve consent
on the server and make no /init request per visit. For output: 'export',
follow static export.
Rendering and deployment compares every
path.
Until the policy resolves, optional categories stay denied and the banner stays hidden.
Configure the backend and the mode
Create an Inth project, set its policy rules and add your site's origin to its trusted origins. A self-hosted backend works the same way with its own URL.
Set NEXT_PUBLIC_C15T_BACKEND_URL to your project's backend URL, including
any path prefix, in .env.local and in your host's build settings:
If your app already sets NEXT_PUBLIC_INTH_PROJECT_URL for other Inth SDKs, that works
too. When both are set, NEXT_PUBLIC_C15T_BACKEND_URL wins.
Create c15t.config.ts at the project root with mode: hosted():
hosted() initializes through ${backendURL}/init and posts choices to
${backendURL}/subjects. Add your scripts to the same config, as the
quickstart shows.
The file is bundled into the browser, so it must hold no secrets.
Wrap next.config.ts in withConsentManifest, which finds c15t.config.ts:
With hosted() it downloads no manifest, so next build does not contact the
backend.
Mount the root without state
The components render their own styles. With Tailwind CSS 3,
load the stylesheet yourself.
In the App Router, render ConsentRoot in the root layout without state:
In the Pages Router, render it in _app.tsx. Without withConsentProps,
pageProps.consent is undefined on every page:
Without server state, ConsentRoot initializes in the browser. Keep it
mounted across client navigation.
Optional same-origin requests
With routePrefix and proxy: true in c15t.config.ts and a consent route
that forwards saves, the browser sends every consent request to your own
origin, which saves it a separate connection to the backend's domain. It
needs a Next.js server. See
optimization.
Verify browser initialization
Open the production build in a fresh browser session with DevTools open.
- The browser calls
${backendURL}/initonce, then shows the banner. No PostHog request runs. - Click Reject All and reload. The banner stays closed and PostHog does not load.
- Open Privacy settings. The rejection is still selected. Turn on
Analytics (the
measurementcategory); PostHog loads. - Block the backend's domain in DevTools and reload in a fresh session. No banner appears and no vendor loads. A hidden banner is not permission.