[C] Consentify

Integration Examples

Examples for integrating the Consentify widget with HTML, React, and Next.js.

All examples use token mode (data-token), the recommended integration. The legacy data-site-id="YOUR_SITE_ID" attribute still works for existing installs - see Widget Installation.

Basic HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Website</title>
</head>
<body>
  <!-- Your page content -->

  <script
    src="https://consentify.dev/widget.js"
    data-token="ct_YOUR_PUBLIC_TOKEN"
    data-position="bottom-right"
    data-theme="auto"
  ></script>
</body>
</html>

Conditional Script Loading

Tag third-party scripts with type="text/plain" and data-consentify naming a category. The browser ignores them, so nothing runs before consent; the widget rewrites them to real scripts once that category is granted. See Script Blocking for details.

<script
  src="https://consentify.dev/widget.js"
  data-token="ct_YOUR_PUBLIC_TOKEN"
></script>

<!-- Held until the visitor grants "analytics" -->
<script
  type="text/plain"
  data-consentify="analytics"
  src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
  async
></script>

This replaces manual onConsentChange injection - the widget handles loading, and the scripts stay blocked for visitors who never consent.

Add data-gcm="true" to push Google Consent Mode v2 signals. The widget sets all consent types to denied by default, then updates them when the visitor decides.

<script
  src="https://consentify.dev/widget.js"
  data-token="ct_YOUR_PUBLIC_TOKEN"
  data-gcm="true"
></script>

<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>

For the default denied signal to be trustworthy, the widget must run before gtag.js - keep the widget script tag above your Google tags.

React / Next.js

For deeper React integration with hooks and programmatic control, see the SDK or Shadcn Registry.

Create a client component that loads the widget:

// components/ConsentWidget.tsx
'use client';

import Script from 'next/script';

export function ConsentWidget() {
  return (
    <Script
      src="https://consentify.dev/widget.js"
      data-token="ct_YOUR_PUBLIC_TOKEN"
      data-position="bottom-right"
      data-theme="auto"
      strategy="afterInteractive"
    />
  );
}

Do not use strategy="lazyOnload". It defers the widget until the browser is idle, so blocked scripts stay inert long after the page is interactive and, with Google Consent Mode, your Google tags load and fire before the widget has set the default denied consent state. Use afterInteractive (or beforeInteractive when you need the widget ahead of Google tags for GCM).

Add it to your root layout:

// app/layout.tsx
import { ConsentWidget } from '@/components/ConsentWidget';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <ConsentWidget />
      </body>
    </html>
  );
}

Add a link that lets users re-open the consent banner to change their preferences:

<a href="#" onclick="window.Consentify.reset(); return false;">
  Manage Cookie Preferences
</a>

On this page