Skip to content

Add a cookie consent banner to any HTML site

One script tag adds the banner and the preference dialog to your site. It holds vendor tags until the visitor chooses, with nothing to install or build.

Ask your coding agent
Sample Consent banner with c15t’s English strings

Add the script tag

c15t is the open source consent library behind Inth Consent. Your Inth project serves it as one script tag, with your backend URL already set.

index.html

<script
  src="https://your-project.inth.app/c15t.js"
  defer
></script>

Paste the tag into the <head> of every page. Replace https://your-project.inth.app with the URL from your Inth project, and keep /c15t.js at the end.

The tag goes in the shared <head> that every page renders.

Examples are the header.php file of a WordPress child theme and the head code setting in Webflow. Others are layout/theme.liquid in Shopify and the base layout of your static site generator. Install on your platform gives the exact place for each platform.

Code on this page comes from the c15t HTML quickstart, checked 28 October 2026.

Hold scripts until consent

Change the type of each vendor tag to text/plain and name its category in data-c15t-category. The browser ignores a text/plain script, so the vendor stays off until c15t runs it.

index.html

<!-- PostHog's snippet, saved as a file on your site -->
<script
  type="text/plain"
  data-c15t-category="measurement"
  src="/posthog.js"
></script>

Remove the original copy of each vendor tag, and the copies that a theme or plugin adds. Use measurement for analytics and marketing for ads and pixels. HTML scripts covers inline snippets and callbacks.

Hold embeds until consent

Move the URL of an iframe from src to data-src and add data-category. c15t sets src after the visitor gives consent for that category.

index.html

<iframe
  data-src="https://www.youtube-nocookie.com/embed/czTksCF6X8Y?playsinline=1"
  data-category="measurement"
  title="YouTube video"
  allow="encrypted-media; picture-in-picture"
  allowfullscreen
></iframe>

Without a src, the iframe loads nothing. HTML embeds has placeholder markup.

index.html

<a href="#c15t-preferences">Privacy settings</a>

index.html

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('consent', 'default', {
    analytics_storage: 'denied',
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
  });
  window.c15t = window.c15t || [];
  c15t.push(['on', 'consent', (snapshot) => {
    const allowed = snapshot.effectivePermissions;
    const state = (granted) => (granted ? 'granted' : 'denied');
    gtag('consent', 'update', {
      analytics_storage: state(allowed.measurement),
      ad_storage: state(allowed.marketing),
      ad_user_data: state(allowed.marketing),
      ad_personalization: state(allowed.marketing),
    });
  }]);
</script>

Show the right banner in each region

Your Inth project sets a policy for each region, such as opt in for the EU and UK or opt out for California. When the tag runs, /init returns the policy for that visitor. A visitor who already chose sees no banner.

Test each region before launch. See how regional policies work.

How the tag loads

With defer, the browser continues to parse the page while the script downloads. When it runs, the tag gets the policy for the visitor and then shows the banner if the policy asks for one. c15t.js leaves out the local policy presets and manifest code.

A page without the tag has no consent state. Check a few pages from different templates after you publish.

Check that consent gates work

Open the site in a private window with the Network tab open. Test under an opt in policy, such as the EU policy.

  1. Under an opt in policy, no PostHog request leaves the page before a choice.
  2. After Reject All and a reload, PostHog stays off.
  3. When you turn on measurement in Privacy settings, PostHog loads.
  4. When you turn measurement off, the page reloads without PostHog.

Choices post to your Inth project. Check that Inth has a record for each one. The c15t verify consent guide has the full release checklist.

Use Inth in production

c15t is open source. Point it at your Inth project, which hosts the backend and keeps the consent records. See Inth open source.

c15t also has a local mode with no backend. It keeps no consent records, so the docs advise against it in production.

Want to see what else your site sends before consent? Run a free codebase scan.

Cookie consent banners for other frameworks

The same banner and the same Inth project work in other stacks. See the setup for Next.js, React, TanStack Start, Nuxt, Vue, Astro, Svelte, SvelteKit and JavaScript.

Do you use a bundler? See the JavaScript cookie consent banner.

See how the Inth consent banner works.

Questions about HTML consent