Consent Manager
How to put the banner on a site, gate tags, and turn on the age gate.
Where it lives
Open Consent Manager from the dashboard. It has four screens: Install, Configure, Cookie scan, and Consent logs. Everything on those screens belongs to the entity selected in the header. Every member of that entity sees the same site, scans, and logs.
What you install
There is no package to install from npm. The site loads one script from consent.complydp.com. That script sets Google Consent Mode to denied for ads and analytics, fetches this site’s settings, shows the banner, and later turns tags on only for categories the visitor allowed. Replace YOUR_SITE_ID with the id from Install.
Plain HTML
Put the loader in the head, before analytics or marketing tags. The defer attribute keeps it from blocking the first paint, and the script still registers Consent Mode before those tags run.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Example</title>
<script src="https://consent.complydp.com/v1/loader.js?site_id=YOUR_SITE_ID" defer></script>
</head>
<body>
<!-- page -->
</body>
</html>Next.js (App Router)
Load the script with next/script and strategy beforeInteractive so it runs before the rest of the app. Put it in the root layout, once.
import Script from "next/script"
const LOADER =
"https://consent.complydp.com/v1/loader.js?site_id=YOUR_SITE_ID"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Script src={LOADER} strategy="beforeInteractive" />
{children}
</body>
</html>
)
}WordPress
There is no WordPress plugin. Add the script from the theme so it prints in the head of every public page. Priority 1 keeps it ahead of most other tags. Do not also paste the script in a header plugin.
add_action('wp_head', function () {
if (is_admin()) {
return;
}
echo '<script src="https://consent.complydp.com/v1/loader.js?site_id=YOUR_SITE_ID" defer></script>';
}, 1);Create the site first
- Sign in and select the right entity.
- Open Consent Manager → Install.
- Enter the domain shoppers type in the browser, such as brand.com, and choose Create site.
- Copy the Site ID into the script above. The Install page also shows the tag already filled in.
Shopify
Do not paste the script into theme.liquid if you use the app. The theme embed injects the same loader. Installing the ComplyDP app does not turn the banner on by itself.
- Install the ComplyDP app on the store and link this organisation.
- Create the consent site with the storefront domain and copy the Site ID.
- In Shopify admin, open Online Store → Themes → Customize → App embeds.
- Turn on ComplyDP consent banner, paste the Site ID, and save.
- Open the storefront in a private window and confirm the banner appears.
The embed also writes the choice into Shopify’s Customer Privacy API, so Shopify’s own pixels follow it. Install, Configure, the scan, and the logs stay on complydp.com.
Stop tags that ignore the banner
The loader records the choice and updates Google Consent Mode (ad_storage, analytics_storage, ad_user_data, ad_personalization). A script tag with a normal src still downloads immediately. For Meta, LinkedIn, PostHog, and similar tags, change the tag so the loader can turn it on after that category is granted. Categories are necessary, functional, analytics, and marketing. Necessary is always on.
<!-- Runs immediately. Do not ship this. -->
<script src="https://snap.licdn.com/li.lms-analytics/insight.min.js"></script>
<!-- Runs only after marketing is allowed. -->
<script
type="text/plain"
data-category="marketing"
src="https://snap.licdn.com/li.lms-analytics/insight.min.js"
></script><script
type="text/plain"
data-category="analytics"
src="https://example.com/analytics.js"
></script>Age gate
The age gate is configured in Consent Manager → Configure, on the Age gate card. Turn on Show age-gate popup, write the question in Default copy, choose an audience mode, and choose Save age gate. No extra script is required. The same loader reads the setting.
The question is a self-declaration, not an identity check. The buttons are fixed: I am 18 or older, and I am under 18. The threshold stored for the site is 18, which matches the DPDP definition of a child. The sentence you type is the question above those buttons. If you add copy for a language, the loader picks the page language (the html lang attribute, then the browser language), then the language without the region, then default.
While the question is on screen, ads and analytics stay denied and only necessary cookies are allowed. The answer is stored in a first-party cookie named complydp_age_band for 180 days. Closing the dialog without answering is stored as unknown. The consent log for that visitor includes the age band: adult, minor, or unknown.
- General or mixed: an adult continues to the normal banner and can allow functional, analytics, and marketing. A minor, or someone who dismisses the question, stays on necessary cookies only. Ads and analytics remain denied.
- Child-directed: the site stays on necessary cookies only, including when the visitor says they are 18 or older.
- The loader does not treat mixed differently from general. Child-directed is the mode that never opens the full banner.
Configure is where you turn the popup on, edit the question, and pick the audience mode. You do not add another script. When the site also has a guardian handoff URL, a minor (or every visitor on a child-directed site) stays on a second overlay: “A parent or guardian can continue”, with a link to that URL. The link is given site_id, visitor_id, and age_band. Dismissing the question does not open that link. Turning the age gate off skips the question and the lock.
Name a logged-in user
Link logged-in users is off until you enable it on Install. Your server mints a short-lived HS256 JWT and the page passes it to the loader after login. Claims: sub (your user id), iss (the site id), aud complydp, exp, and jti. Optional emh is HMAC-SHA256 of the identity secret and the lowercased trimmed email. Old logs stay anonymous. On logout call unidentify.
const crypto = require("crypto")
const jwt = require("jsonwebtoken")
function complydpToken(user) {
const email = user.email.trim().toLowerCase()
const emh = crypto
.createHmac("sha256", process.env.COMPLYDP_IDENTITY_SECRET)
.update(email)
.digest("hex")
return jwt.sign(
{ emh },
process.env.COMPLYDP_IDENTITY_SECRET,
{
subject: String(user.id),
issuer: process.env.COMPLYDP_SITE_ID,
audience: "complydp",
expiresIn: "15m",
jwtid: crypto.randomUUID(),
},
)
}ComplyDP.identify(token)
// later
ComplyDP.unidentify()Configure, scan, and logs
- Configure sets the banner title, description, colours, cookie categories, and the age gate. Save, then reload the site. You do not edit the theme again for wording or colours.
- Cookie scan visits the domain and lists cookies so you can place them in a category.
- Consent logs are the recorded choices, including the age band when the age gate is on.
Disconnect
Disconnect website removes the site from this entity so you can register another domain. The script already on the site keeps loading the banner. To stop the popup, remove that script. On Shopify, turn off the ComplyDP consent banner app embed.