ConsentProof Verify a receipt · تحقق من إيصال Start free · ابدأ مجاناً

Widget & cookie banner الودجت ولافتة الكوكيز

الخلاصة بالعربية وسم واحد يعرض لافتة موافقة ثنائية اللغة سليمة الاتجاه بهوية علامتك، ويحجب سكربتات التتبع حتى تصدر الموافقة، ويسلّم العميل إيصاله. ضمانات النظام مدمجة في الواجهة نفسها: خيارات الموافقة غير مؤشَّرة افتراضياً، الحفظ فعل صريح، والإغلاق لا يسجّل شيئاً. لن تعمل اللافتة على موقعك حتى تضيف عنوانه في «مصادر الودجت» بلوحة التحكم — قائمة سماح لكل منشأة، لا إعداد عام.

One script tag. Zero dependencies, ~30 KB, bilingual and RTL-correct, themed to your brand. It renders the banner, records decisions with receipts, gates your tracking scripts, and hosts the subject's rights UI.

<script src="https://your-host/static/consent.js"></script> <script> ConsentProof.init({ pk: "cp_pk_…", apiBase: "https://your-host/v1", policy: "privacy", // optional, default "privacy" language: "ar", // optional, defaults to org setting reentryPill: true, // persistent "privacy settings" pill googleConsentMode: true, // drive gtag Consent Mode v2 subjectToken: "cps_…", // optional: unlocks the full rights center }); </script>

It will not load until you allow your origin under API keys → Widget origins. Widget CORS is a per-organization allowlist.

PDPL guarantees baked into the UI

  • Consent-basis purposes are unchecked by default, always — a pre-ticked box is not consent.
  • Non-consent bases (contract, legal obligation, legitimate interest) render as informational rows, not checkboxes — you don't ask for what you don't need to ask for.
  • Saving is an explicit visible action; closing with Esc records nothing (dismissal ≠ consent).
  • After deciding, the subject sees their own receipt_id with a public verify link — the receipt is theirs too.

Gating trackers until consent

Mark the tag inert; the widget activates it only after its purpose is granted — and on withdrawal it stays off at the next load:

<script type="text/plain" data-cp-purpose="analytics" src="https://analytics.example/tag.js"></script> <!-- iframes: omit src, use data-cp-src; a themed placeholder holds the space --> <iframe data-cp-purpose="marketing" data-cp-src="https://youtube.com/embed/…"></iframe>

Google Consent Mode v2

With googleConsentMode: true the widget signals gtag defaults as denied before any Google tag runs, maps purpose decisions to ad_storage / analytics_storage / ad_user_data / ad_personalization, and re-signals on withdrawal. Override the mapping per purpose with consentModeMap.

State queries

ConsentProof.check("analytics") // "active" | "denied" | "withdrawn" | null ConsentProof.receipt("analytics") // "rcp_…" | null ConsentProof.open() // reopen the banner in manage mode

Theming

Set brand color, radius and logo once in the dashboard (Branding) — banner, hosted policy page and rights pages all follow. Host-page CSS variables win if you need per-site control:

:root { --cp-accent: #17714E; --cp-bg: #161D1A; --cp-ink: #F2F1E9; }

Keep contrast ≥ 4.5:1 — the sanitizer refuses branding values that would make the banner unreadable.

The rights center in the widget

See Privacy center & rights — embedded mode (your backend mints a subject token) and anonymous mode (localStorage record, plus "add your phone/email" claim that upgrades it) are both handled by the same ConsentProof.openPrivacyCenter().