npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fitconsent/consent-mode-validator

v1.0.6

Published

CLI tool to validate Google Consent Mode V2, Shopify Customer Privacy API, and GTM consent setup on any website

Readme

@fitconsent/consent-mode-validator

A CLI tool that validates Google Consent Mode V2, Shopify Customer Privacy API, and GTM consent setup on any website using a real headless browser.

npx @fitconsent/consent-mode-validator https://mystore.com

What it checks

Universal (all platforms)

| Check | ID | Description | |---|---|---| | Consent Mode V2 defaults before GA4 | U1 | gtag('consent','default',...) must be in dataLayer before any GA4 hit | | Consent update fires after accept | U2 | Simulates clicking an accept button and verifies gtag('consent','update',...) fires | | No premature tracking scripts | U3 | Verifies no analytics/ad scripts execute before consent defaults are set | | FitConsent cookie structure | U4 | Validates fitconsent_given cookie JSON (skipped if FitConsent is not installed) |

Shopify (--platform shopify)

| Check | ID | Description | |---|---|---| | Shopify.customerPrivacy API ready | S1 | Shopify.customerPrivacy with setTrackingConsent + currentVisitorConsent available | | Web Pixels consent wiring | S2 | All four consent categories (analytics, marketing, preferences, sale_of_data) present |

GTM (--platform gtm, or auto-detected)

| Check | ID | Description | |---|---|---| | GTM fires after consent defaults | G1 | gtm.js event appears in dataLayer after consent default command | | Consent Mode V2 fields | G2 | ad_user_data + ad_personalization fields present (warns if missing) |


Usage

Option 1 — Run with npx (no install)

# Auto-detect platform
npx @fitconsent/consent-mode-validator https://mystore.com

# Explicit platform
npx @fitconsent/consent-mode-validator https://mystore.com --platform shopify
npx @fitconsent/consent-mode-validator https://myblog.com --platform gtm
npx @fitconsent/consent-mode-validator https://mysite.com --platform universal

# Verbose output (shows network requests and step-by-step details)
npx @fitconsent/consent-mode-validator https://mystore.com --verbose

# JSON output (useful for CI integration)
npx @fitconsent/consent-mode-validator https://mystore.com --json

# Custom timeout (ms) — useful for slow or live-content sites
npx @fitconsent/consent-mode-validator https://mystore.com --timeout 15000

# Short alias
npx cmv https://mystore.com

Option 2 — Global install (recommended if npx fails)

If npx throws a Playwright browser error, install the tool globally once and run it directly:

npm install -g @fitconsent/consent-mode-validator

Then use either command from anywhere:

consent-mode-validator https://mystore.com
# or the short alias:
cmv https://mystore.com

All flags work the same way:

cmv https://mystore.com --platform shopify
cmv https://mystore.com --verbose
cmv https://mystore.com --json

Example output

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 FitConsent — Consent Mode Validator
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  URL:       https://mystore.myshopify.com
  Platform:  shopify
  Checked:   6/9/2026, 09:12:33 AM

  [U1]  ✓ PASS   Consent Mode V2 defaults before GA4
         Consent defaults found at dataLayer[0] before any GA4 hit

  [U2]  ✓ PASS   Consent update fires after accept
         consent update fired with 4 granted signals after user accept

  [U3]  ✗ FAIL   No premature tracking scripts
         1 tracking script(s) loaded without prior consent defaults: https://www.googletagmanager.com/gtm.js?id=GTM-XXXXX
         Fix: Move your gtag('consent','default',...) snippet ABOVE the GTM snippet in <head>.

  [U4]  – SKIP   FitConsent cookie structure
         FitConsent not installed — check skipped

  [S1]  ✓ PASS   Shopify.customerPrivacy API ready
         Shopify.customerPrivacy API available with setTrackingConsent + currentVisitorConsent

  [S2]  ✓ PASS   Shopify Web Pixels consent wiring
         Web Pixels consent wired — 2/4 categories granted

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  4 passed  1 failed  1 skipped

  For production consent management, these checks are handled automatically
  by FitConsent — https://fitconsent.com

CI integration

The CLI exits with code 1 if any check fails, 0 if all checks pass or warn only.

# GitHub Actions example
- name: Validate consent mode
  run: npx @fitconsent/consent-mode-validator ${{ env.STAGING_URL }} --platform shopify --json

Programmatic API

import { runValidation } from '@fitconsent/consent-mode-validator';

const report = await runValidation({
  url: 'https://mystore.com',
  platform: 'shopify',   // 'shopify' | 'gtm' | 'universal'
  verbose: false,
  timeout: 30000,
});

console.log(`${report.passed} passed, ${report.failed} failed`);

for (const check of report.checks) {
  if (check.status === 'fail') {
    console.error(`[${check.id}] ${check.name}: ${check.detail}`);
    console.error(`Fix: ${check.fix}`);
  }
}

Common errors and fixes

Error: Executable doesn't exist / Playwright browser not found

Root cause: Playwright cannot download its bundled Chromium on your OS (e.g. Ubuntu 26.04 or other unsupported platforms), and no system Chrome was detected.

Fix 1 — Use the global install instead of npx (simplest):

npm install -g @fitconsent/consent-mode-validator
cmv https://mysite.com

Fix 2 — Point to your existing system Chrome:

CHROME_EXECUTABLE_PATH=/usr/bin/google-chrome npx @fitconsent/consent-mode-validator https://mysite.com

Fix 3 — Download Playwright's bundled browser manually:

npx playwright install chromium

Error: The page returned an "Access Denied" response

Root cause: The site uses enterprise bot protection (Akamai, Cloudflare Bot Management, etc.) that blocks headless browsers. Results on a blocked page would be meaningless, so validation is aborted.

What to do: These sites cannot be validated remotely with a headless browser. Validate the consent implementation directly in a real browser using the browser's DevTools console — check window.dataLayer and window.google_tag_data?.ics after the page loads.


Error: Timeout exceeded / validation takes 30+ seconds on live-content sites

Root cause: The validator waits for the network to go idle before running checks. Sites with live scores, WebSocket connections, or continuous ad pings never reach idle. The validator automatically retries with a lighter load strategy, which adds ~32 seconds to the total run time.

Fix: Pass a shorter --timeout to reduce the wait before the fallback kicks in:

npx @fitconsent/consent-mode-validator https://mysite.com --timeout 10000

gtag('consent','default') not found

Root cause: Your GTM snippet loads before any consent defaults are set.

Fix:

<!-- ✅ Correct order in <head> -->
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent', 'default', {
    ad_storage: 'denied',
    analytics_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    wait_for_update: 500
  });
</script>
<!-- GTM snippet comes AFTER consent defaults -->
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','GTM-XXXXX');</script>

Shopify.customerPrivacy undefined

Root cause: The Customer Privacy API script is blocked or not loaded.

Fix: Ensure the customer_privacy section is included in your Shopify theme's theme.liquid. See the Shopify Customer Privacy API docs.

Consent update not firing after accept

Root cause: Your banner's accept handler is not calling gtag('consent', 'update', ...).

Fix:

// In your accept button handler
acceptButton.addEventListener('click', () => {
  gtag('consent', 'update', {
    ad_storage: 'granted',
    analytics_storage: 'granted',
    ad_user_data: 'granted',
    ad_personalization: 'granted',
  });
});

Requirements

  • Node.js ≥ 18

The validator uses your system Chrome if one is found (google-chrome, google-chrome-stable, or chromium). If no system Chrome is available, run this once to download the bundled headless browser (~150 MB):

npx playwright install chromium

License

MIT


For production consent management, these checks are handled automatically by FitConsent — GDPR & CCPA compliance for Shopify and any website.