Skip to main content

10 frameworks, one cookie banner.

Next.js to plain HTML. Each framework has a quickstart and its own guides. Pick yours, or let your coding agent set c15t up.

Not sure which setup your app needs? Find your app.

Pick your framework.

Each quickstart takes you from install to a banner you can check in the browser.

Four steps in every framework.

Start with one file. Follow your framework's quickstart for the full setup, then move your scripts into c15t.

components/consent.tsx
import {
	ConsentBanner, ConsentDialog, ConsentDialogLink, ConsentRoot,
} from 'c15t/next';
import { defineConsentConfig, resolveConsent } from 'c15t/next/server';
import type { ReactNode } from 'react';

export const consentConfig = defineConsentConfig({
	backendURL: 'https://your-project.inth.app',
});

export function Consent({ children }: { children: ReactNode }) {
	const state = resolveConsent({ config: consentConfig });

	return (
		<ConsentRoot state={state} config={consentConfig}>
			{children}
			<ConsentBanner />
			<ConsentDialog />
			<ConsentDialogLink>Privacy settings</ConsentDialogLink>
		</ConsentRoot>
	);
}

Also in TanStack Start, React, Vue, Svelte, SvelteKit and JavaScript.

One package.

Install c15t and import the entry point for your framework. You do not need @c15t/nextjs or @c15t/react as well.

  • npm install c15t

    • Next.jsc15t/next
    • TanStack Startc15t/tanstack-start
    • Reactc15t/react
    • Nuxtc15t/vue
    • Vuec15t/vue/vue-plugin
    • Astroc15t/astro
    • JavaScriptc15t/runtime

    c15t

    Next.js, TanStack Start, React, Nuxt, Vue, Astro, and JavaScript import from c15t.

  • @c15t/integrations

    Helpers for analytics, pixels, chat and embeds, a separate install in every framework.

Svelte, SvelteKit, and HTML use their own package: @c15t/svelte and @c15t/browser.

Find your app.

Most apps need one row. Follow its guide from start to finish. The whole table is in Choose your setup.

  • Next.js App Router with a Next.js server

    Server resolves consent from a build-time manifest and streams it to the page

    App Router
  • Next.js App Router, page must arrive with its banner

    Await consent inside Suspense

    Stream or await
  • Next.js with static, ISR, 'use cache' or ensureStatic = 'navigation' pages

    Browser resolves consent on those pages

    Static, ISR and cached pages
  • Next.js Pages Router

    Resolve consent in getServerSideProps

    Pages Router
  • Next.js with output: 'export'

    Browser resolves consent

    Static export

After the quickstart.

A banner on screen does not mean analytics wait for consent. Move existing scripts into c15t, replace embeds that load on their own, and keep a link to reopen preferences. Then verify the integration.