1. Home
  2. Tools and Templates
  3. TNT Cookie Consent Manager – Developer Guide

TNT Cookie Consent Manager – Developer Guide

Overview

The TNT Cookie Consent Manager is a lightweight, dependency-free solution that allows visitors to opt out of analytics, advertising, and other tracking while ensuring necessary site functionality always works.

Key Files:

Main JavaScript consent manager

Styling for the consent banner

PHP Consent Manager (Blog)

Important: These three files remain the same across all TNT Dental sites. Upload once and reference from templates.


Quick Start

Step 1: File Deployment

Deploy the three core files to your site:

httpdocs/
├── tnt-consent.css          ← CSS in root directory
└── assets/
    ├── js/
    │   └── tnt-consent.js   ← JavaScript file
    └── php/
        └── tnt-consent.php  ← PHP file (WordPress only)

Step 2: Add to HTML Template

Copy and paste this HTML into your site’s <head> section, before any tracking scripts:

<!-- TNT Cookie Consent CSS -->
<link href="tnt-consent.css" rel="stylesheet">

<!-- TNT Cookie Consent Manager - Must load before conditional scripts -->
<script src="/assets/js/tnt-consent.js"></script>

Full example of head section:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Your Page Title</title>
    
    <!-- TNT Cookie Consent CSS -->
    <link href="tnt-consent.css" rel="stylesheet">
    
    <!-- TNT Cookie Consent Manager - Must load before conditional scripts -->
    <script src="/assets/js/tnt-consent.js"></script>
    
    <!-- Your other CSS files -->
    <link href="styles.css" rel="stylesheet">
    
    <!-- Tracking scripts go here (see conversion examples below) -->
</head>

Add this HTML to your footer template:

<a href="#" onclick="if (window.TNTConsentReset) { TNTConsentReset(); } return false;">
  Cookie preferences
</a>

Full footer example:

<footer>
    <div class="footer-content">
        <p>&copy; 2025 Your Site Name</p>
        <p>
            <a href="privacy-policy.html">Privacy Policy</a> | 
            <a href="#" onclick="if (window.TNTConsentReset) { TNTConsentReset(); } return false;">Cookie preferences</a>
        </p>
    </div>
</footer>

Working Example

sounddentist.com


Converting Existing Tracking Scripts

The Conversion Pattern

Before (regular script that loads immediately):

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

After (consent-aware script that waits for permission):

<script type="text/plain" 
        data-tnt-category="analytics" 
        data-src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" 
        data-async="true"></script>

Conversion Rules:

  1. Change script type: type="text/javascript"type="text/plain" (prevents browser from executing)
  2. Move src attribute: src="..."data-src="..."

  3. Add category: Add data-tnt-category="analytics" (or advertising or other)
  4. Move async/defer: asyncdata-async="true" or deferdata-defer="true"

Converting Tracking Scripts

When you need to add a new tracking script (like Facebook Pixel, new analytics tool, etc.), follow these steps:

Step 1: Identify the Category

Choose the appropriate category:

  • analytics – Google Analytics, Adobe Analytics, heatmaps, user behavior tracking
  • advertising – Google Ads, Facebook Pixel, remarketing pixels, ad networks
  • other – Social widgets, chat widgets, other third-party tracking

Step 2: Convert Using HTML Examples Below

Use the examples in the next section as templates. Copy the HTML structure and replace with your script’s details.


Common Script Examples

Facebook Pixel (Advertising Category)

Original Facebook Pixel HTML:

<!-- Facebook Pixel Code -->
<script>
  !function(f,b,e,v,n,t,s)
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
  n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
  n.queue=[];t=b.createElement(e);t.async=!0;
  t.src=v;s=b.getElementsByTagName(e)[0];
  s.parentNode.insertBefore(t,s)}(window, document,'script',
  'https://connect.facebook.net/en_US/fbevents.js');
  fbq('init', 'YOUR_PIXEL_ID');
  fbq('track', 'PageView');
</script>
<noscript>
  <img height="1" width="1" style="display:none"
       src="https://www.facebook.com/tr?id=YOUR_PIXEL_ID&ev=PageView&noscript=1"/>
</noscript>

Converted HTML for Consent:

<!-- Facebook Pixel Code - Requires Advertising Consent -->
<script type="text/plain" data-tnt-category="advertising">
  !function(f,b,e,v,n,t,s)
  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
  n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
  n.queue=[];t=b.createElement(e);t.async=!0;
  t.src=v;s=b.getElementsByTagName(e)[0];
  s.parentNode.insertBefore(t,s)}(window, document,'script',
  'https://connect.facebook.net/en_US/fbevents.js');
  fbq('init', 'YOUR_PIXEL_ID');
  fbq('track', 'PageView');
</script>
<noscript>
  <img height="1" width="1" style="display:none"
       src="https://www.facebook.com/tr?id=YOUR_PIXEL_ID&ev=PageView&noscript=1"/>
</noscript>

What changed: Added type="text/plain" and data-tnt-category="advertising" to the <script> tag.


Google Analytics 4 (GA4) – Analytics Category

Original GA4 HTML:

<!-- Google Analytics GA4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

Converted HTML for Consent:

<!-- Google Analytics GA4 - Requires Analytics Consent -->
<script type="text/plain" 
        data-tnt-category="analytics"
        data-src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" 
        data-async="true"></script>
<script type="text/plain" data-tnt-category="analytics">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

What changed:

  • First script: srcdata-src, asyncdata-async="true", added type="text/plain" and data-tnt-category="analytics"
  • Second script: Added type="text/plain" and data-tnt-category="analytics"

Original Google Ads HTML:

<!-- Google Ads Remarketing -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('config', 'AW-XXXXXXXXXX');
</script>

Converted HTML for Consent:

<!-- Google Ads Remarketing - Requires Advertising Consent -->
<script type="text/plain" 
        data-tnt-category="advertising"
        data-src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXXXXXXX" 
        data-async="true"></script>
<script type="text/plain" data-tnt-category="advertising">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('config', 'AW-XXXXXXXXXX');
</script>

What changed: Same pattern as GA4, but using data-tnt-category="advertising" instead.


Chat Widget (LiveChat, Intercom, etc.) – Other Category

Original Chat Widget HTML:

<!-- LiveChat Widget -->
<script>
  window.__lc = window.__lc || {};
  window.__lc.license = YOUR_LICENSE_ID;
  (function() {
    var lc = document.createElement('script');
    lc.type = 'text/javascript';
    lc.async = true;
    lc.src = 'https://cdn.livechatinc.com/tracking.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(lc, s);
  })();
</script>

Converted HTML for Consent:

<!-- LiveChat Widget - Requires Other Tracking Consent -->
<script type="text/plain" data-tnt-category="other">
  window.__lc = window.__lc || {};
  window.__lc.license = YOUR_LICENSE_ID;
  (function() {
    var lc = document.createElement('script');
    lc.type = 'text/javascript';
    lc.async = true;
    lc.src = 'https://cdn.livechatinc.com/tracking.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(lc, s);
  })();
</script>

What changed: Added type="text/plain" and data-tnt-category="other" to the <script> tag.


Simpli.fi Tracking – Advertising Category

Original Simpli.fi HTML:

<script async src="https://tag.simpli.fi/sifitag/d0839950-0d38-0137-dfb5-06a9ed4ca31b"></script>

Converted HTML for Consent:

<script type="text/plain" 
        data-tnt-category="advertising"
        data-src="https://tag.simpli.fi/sifitag/d0839950-0d38-0137-dfb5-06a9ed4ca31b" 
        data-async="true"></script>

What changed: srcdata-src, asyncdata-async="true", added type="text/plain" and data-tnt-category="advertising".


HTML Pattern Reference

Pattern 1: External Script with Async

Before:

<script async src="https://example.com/tracker.js"></script>

After:

<script type="text/plain" 
        data-tnt-category="analytics" 
        data-src="https://example.com/tracker.js" 
        data-async="true"></script>

Pattern 2: External Script with Defer

Before:

<script defer src="https://example.com/tracker.js"></script>

After:

<script type="text/plain" 
        data-tnt-category="advertising" 
        data-src="https://example.com/tracker.js" 
        data-defer="true"></script>

Pattern 3: Inline Script (No External File)

Before:

<script>
  // Your tracking code here
  console.log('Tracking initialized');
</script>

After:

<script type="text/plain" data-tnt-category="analytics">
  // Your tracking code here
  console.log('Tracking initialized');
</script>

Pattern 4: Multiple Scripts (Like GA4)

Before:

<script async src="https://example.com/loader.js"></script>
<script>
  initTracker('YOUR_ID');
</script>

After:

<script type="text/plain" 
        data-tnt-category="analytics"
        data-src="https://example.com/loader.js" 
        data-async="true"></script>
<script type="text/plain" data-tnt-category="analytics">
  initTracker('YOUR_ID');
</script>

Important: Both scripts must have the same data-tnt-category value.


Complete HTML Template Example

Here’s a complete <head> section showing how everything fits together:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Your Page Title</title>
    
    <!-- Site CSS -->
    <link href="styles.css" rel="stylesheet">
    
    <!-- TNT Cookie Consent CSS -->
    <link href="tnt-consent.css" rel="stylesheet">
    
    <!-- TNT Cookie Consent Manager - Must load before conditional scripts -->
    <script src="/assets/js/tnt-consent.js"></script>
    
    <!-- Converted tracking scripts - These will only load if user consents -->
    
    <!-- Google Analytics GA4 - Analytics -->
    <script type="text/plain" 
            data-tnt-category="analytics"
            data-src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" 
            data-async="true"></script>
    <script type="text/plain" data-tnt-category="analytics">
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'G-XXXXXXXXXX');
    </script>
    
    <!-- Facebook Pixel - Advertising -->
    <script type="text/plain" data-tnt-category="advertising">
      !function(f,b,e,v,n,t,s)
      {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
      n.callMethod.apply(n,arguments):n.queue.push(arguments)};
      if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
      n.queue=[];t=b.createElement(e);t.async=!0;
      t.src=v;s=b.getElementsByTagName(e)[0];
      s.parentNode.insertBefore(t,s)}(window, document,'script',
      'https://connect.facebook.net/en_US/fbevents.js');
      fbq('init', 'YOUR_PIXEL_ID');
      fbq('track', 'PageView');
    </script>
    
    <!-- Site's own JavaScript (NOT converted - always loads) -->
    <script src="/assets/js/scripts.js"></script>
</head>
<body>
    <!-- Your page content -->
    
    <footer>
        <p>
            <a href="privacy-policy.html">Privacy Policy</a> | 
            <a href="#" onclick="if (window.TNTConsentReset) { TNTConsentReset(); } return false;">Cookie preferences</a>
        </p>
    </footer>
</body>
</html>

Scripts That Should NOT Be Converted

Never convert these (they’re necessary for site functionality):

<!-- Site's own JavaScript files -->
<script src="/assets/js/scripts.js"></script>
<script src="/assets/js/foundation.js"></script>

<!-- Form validation -->
<script src="/assets/js/validator.js"></script>

<!-- Navigation/menu scripts -->
<script src="/assets/js/menu.js"></script>

Rule of thumb: If removing the script breaks the site, don’t convert it. Only convert third-party tracking/analytics scripts.


WordPress Blog Integration

  1. Install the Header/Footer Plugin if not already installed
  2. Click the “Update” Theme button

Testing Checklist

  • Clear browser cookies for the site
  • Reload the page
  • Banner should appear at the bottom

2. Test Script Loading

  • Open browser DevTools → Network tab
  • Accept all consent categories
  • Verify tracking scripts load (check for requests to Google Analytics, Facebook, etc.)

3. Test Script Blocking

  • Clear cookies and reload
  • Click “Reject non-essential”
  • Verify tracking scripts do NOT load in Network tab
  • Set consent preferences
  • Navigate to different pages
  • Consent should persist (no banner on subsequent pages)
  • Click “Cookie preferences” link in footer
  • Banner should reappear
  • Changes should take effect immediately

Troubleshooting

  • Check that tnt-consent.js is loaded (check Network tab in DevTools)
  • Check browser console for JavaScript errors
  • Verify CSS file is loaded
  • Ensure scripts are in <head> before other scripts
  • Verify script has type="text/plain" (not type="text/javascript")
  • Check data-tnt-category attribute is present
  • Ensure tnt-consent.js loads before the tracking scripts
  • Check browser console for errors
  • Check cookie is being set (DevTools → Application → Cookies)
  • Verify cookie name is tnt_consent_v1
  • Check cookie path is / (should be available site-wide)
  • Ensure no ad blockers are interfering
  • Verify Header/Footer Plugin correctly installed and working
  • If using client-side, ensure JS/CSS are loaded on blog pages

Quick Reference: Adding a New Script

When you encounter a new tracking script:

Step 1: Identify the Category

  • Analytics tool? → data-tnt-category="analytics"
  • Ad network/pixel? → data-tnt-category="advertising"
  • Chat/social widget? → data-tnt-category="other"

Step 2: Convert the HTML

If it’s an external script:

<!-- Change this -->
<script async src="https://example.com/tracker.js"></script>

<!-- To this -->
<script type="text/plain" 
        data-tnt-category="analytics" 
        data-src="https://example.com/tracker.js" 
        data-async="true"></script>

If it’s an inline script:

<!-- Change this -->
<script>
  // tracking code
</script>

<!-- To this -->
<script type="text/plain" data-tnt-category="analytics">
  // tracking code
</script>

Step 3: Test It

  • Clear cookies and reload
  • Reject the category
  • Verify script doesn’t load in Network tab
  • Accept the category
  • Verify script loads

Checklist for New Sites

  • Upload tnt-consent.css to root directory
  • Upload tnt-consent.js to /assets/js/
  • Add CSS and JS links to template <head>
  • Add “Cookie preferences” link to footer
  • Convert all tracking scripts to type="text/plain" format
  • Test banner appears on first visit
  • Test scripts load after consent
  • Test scripts blocked when consent denied
  • Test consent persists across pages
  • (WordPress only) Install PHP plugin if using server-side approach

Last Updated: January 2025

Updated on November 16, 2025
Was this article helpful?

Related Articles