Build your own Custom integration

Custom integration

Markdown
Loading…

Load any script only after consent, with customScript() or a small integration object of your own.

Two ways to gate a tool that has no ready-made integration. customScript() covers most cases: give it a script URL and a category. Write an integration object of your own when the tool needs more, for example a call to its own consent API instead of removing the script.

Install the integrations package and add customScript() to the initCookieYes() call you already have:

npm install @cookieyes/scripts
app/consent-manager.tsx
"use client";

import { initCookieYes } from "@cookieyes/nextjs";
import { customScript } from "@cookieyes/scripts";

initCookieYes({
  mode: "cookie-only",
  regulation: "GDPR",
  integrations: [
    customScript({
      id: "chat-widget",
      src: "https://cdn.example.com/widget.js",
      category: "functional",
    }),
  ],
});

The script is added to the page when the visitor grants the category, and removed again when consent is withdrawn.

Options

OptionDefaultWhat it does
idrequiredA unique name for this script
srcrequiredThe script URL
categoryrequiredThe category the visitor must grant. Pass an array to require several
match"all"With several categories: "all" needs every one granted, "any" needs one
onRevoke"remove""remove" takes the script off the page on withdrawal. "keep" leaves it; only for a script that handles consent itself
attrsnoneExtra attributes for the <script> tag, such as a nonce for a strict CSP
stubnoneQueue calls made before the script loads: { global: "myTag", methods: ["track"] }

Write your own integration

An integration is a plain object. setup runs when the category is granted. What it returns depends on onRevoke:

  • "remove": return a cleanup function. It runs on withdrawal, and setup runs again on the next grant.
  • "silence": return { silence, resume }. The tool stays loaded and is told to pause and continue.
  • "keep": return nothing. The tool handles consent itself.
src/my-vendor.ts
import type { Integration } from "@cookieyes/core";

export const myVendor: Integration = {
  id: "my-vendor",
  category: "analytics",
  version: 1, // the integration format version
  load: "afterConsent",
  onRevoke: "remove",
  setup: () => {
    const script = document.createElement("script");
    script.src = "https://cdn.example.com/vendor.js";
    document.head.appendChild(script);
    return () => script.remove();
  },
};

Add it to integrations like any other. setup receives a context with granted(), onConsentChange(fn) and the visitor's region, for a tool that has to react to changes itself.

Keep load: "afterConsent" unless the tool stays silent until it is told otherwise, as Google tags do under Consent Mode. load: "immediately" runs setup before the visitor has decided.

Check it works

Open your site in a private window and watch the Network tab and the cookies:

  1. Before a decision: nothing loads.
  2. Accept: the script loads.
  3. Withdraw consent in the preferences dialog: "remove" takes the script off the page, "silence" pauses it.

To see every integration with its current status, run this in the console:

import { getCookieYes } from "@cookieyes/nextjs";

console.table(getCookieYes().getIntegrations());

Common mistakes

The script never loads, even after accept. Its category is not in your categories list, so it can never be granted. The SDK logs a warning naming it. Check the spelling against Configuration → Consent categories.

The tool's global is undefined when you call it. The call ran before consent. Use the stub option to queue calls, or guard the call with safeCall() from @cookieyes/scripts.

The script runs before the visitor has decided. The integration has load: "immediately". Use "afterConsent".

Next steps

On this page