Skip to main content

HTML

Quickstart

Connect Inth

Create an Inth project, set its policy rules, add your site's origin to its trusted origins, and copy the project's backend URL. The URL is public configuration. It ends up in your page's HTML, which is expected.

This guide loads @c15t/browser from your Inth project with a <script> tag. The tag brings the banner, the preference dialog, stored choices and script gating. There is nothing to install or build. If your site has a bundler, the same package is available as an ES module; choose your setup lists both paths.

Add the script tag

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

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

Inth serves the hosted bundle with your project's backend URL already configured, so the tag needs no data-backend-url. defer lets the page keep parsing while the script downloads. When it runs, the tag resolves the visitor's policy through Inth's /init, then shows the banner if the policy asks for one. A returning visitor who already chose sees no banner. Attributes from the attribute reference, such as data-language, still work on this tag.

c15t.js keeps the stock UI and consent behavior while excluding offline policy presets, offline resolution and manifest transport code. /init returns the policy resolved for this visitor.

Where to paste it

The tag belongs in the shared <head> that every page renders, such as a WordPress child theme's header.php, Webflow's head code setting, Shopify's layout/theme.liquid, or your static site generator's base layout. Install on your platform gives the exact place for each platform, and what to check in caching plugins and tag managers.

A page without the tag has no consent state, and its vendor scripts follow their own rules. Check a few pages from different templates after you publish.

Gate your vendor scripts

The tag only controls scripts it knows about. Change each vendor tag's type 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 sees permission for that category and runs the script.

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

The PostHog tag loads the vendor's snippet from a file on your site. Save the snippet from your PostHog project settings as that file. A vendor snippet you paste inline works the same way: keep it inside the tag and change the tag's type and category.

Remove the original, active copy of each vendor tag, including copies a theme setting or another plugin adds. Use measurement for analytics and marketing for ads and pixels. Consent categories lists all five. Gated scripts covers load order, and scripts covers callbacks and what happens when a visitor withdraws permission.

Gate embeds

Move an iframe's URL from src to data-src and add data-category. c15t sets src once the category is allowed and removes it again if the visitor withdraws permission.

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. Show a placeholder next to it with CSS, such as iframe:not([src]) { display: none; } and a message that links to privacy settings. Embeds has the full placeholder markup.

Visitors need a way to change their choice after the banner closes. A link to #c15t-preferences opens the preference dialog, with no JavaScript on your page:

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

Put it in the footer of every page. A button with data-c15t-action="customize" does the same, and data-trigger on the script tag adds a floating button instead. Components lists every surface and page hook.

Check it works

Open the site in a private window with the browser's developer tools open on the Network tab.

  1. Before you choose, filter for posthog. There are no requests, and the YouTube iframe has no src.
  2. Click Reject All and reload. The banner stays closed and the PostHog requests stay absent.
  3. Open Privacy settings, turn on Analytics (the measurement category) and save. PostHog's array.js and the YouTube player load.
  4. Open Privacy settings again and turn Analytics off. The page reloads, and PostHog and YouTube do not load again.

If no banner appears, the policy for your location may not ask for one. See troubleshooting. Run the full verification checklist before you ship.

Other ways to run the tag

  • Offline mode. Load c15t.offline.js from a CDN, without data-backend-url, and c15t resolves the policy in the browser from data-policy-rules or its recommended rules. The browser does not know the visitor's country, so without data-country every visitor gets the strict opt-in fallback. Choices stay in that browser and there are no consent records. Not recommended for production environments.
  • A self-hosted backend. A self-hosted c15t backend serves the hosted bundle at /c15t.js with its backend URL already configured, so the tag needs only a src: <script src="https://consent.example.com/c15t.js" defer></script>, with your backend's origin in place of consent.example.com.
  • From a CDN. Load a pinned version from jsDelivr. Use c15t.js with data-backend-url for hosted mode: <script src="https://cdn.jsdelivr.net/npm/@c15t/browser@<version>/dist/c15t.js" data-backend-url="https://your-project.inth.app" defer></script>. For offline mode, use dist/c15t.offline.js without data-backend-url. Replace <version> with the exact version listed on npm. @alpha loads the newest v3 prerelease, so a new release can change your banner without a deploy.
  • Manifest mode. Use the @c15t/browser ES module for manifest mode with the stock UI, or c15t.headless.js with your own UI. These clients can fetch or inline the backend's cacheable policy manifest. The IAB script also supports manifest mode for IAB policies. See modes.

Next steps