PHPackages                             fendinger/kirby-consent-gate - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. fendinger/kirby-consent-gate

ActiveKirby-plugin[Utility &amp; Helpers](/categories/utility)

fendinger/kirby-consent-gate
============================

GDPR compliant external content blocker for Kirby CMS

1.0.0(1mo ago)713↓33.3%MITPHP

Since Apr 15Pushed 1mo agoCompare

[ Source](https://github.com/fendinger/kirby-consent-gate)[ Packagist](https://packagist.org/packages/fendinger/kirby-consent-gate)[ Docs](https://github.com/fendinger/kirby-consent-gate)[ RSS](/packages/fendinger-kirby-consent-gate/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

[![Kirby Consent Gate](https://private-user-images.githubusercontent.com/41189281/578813564-899442db-d32b-4334-a3d8-e140902d6fc0.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODA5NzQ3ODQsIm5iZiI6MTc4MDk3NDQ4NCwicGF0aCI6Ii80MTE4OTI4MS81Nzg4MTM1NjQtODk5NDQyZGItZDMyYi00MzM0LWEzZDgtZTE0MDkwMmQ2ZmMwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA2MDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNjA5VDAzMDgwNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTFkMTRhOTlmYzA2ZTEwNzI2YmZmODRmNDJjMDc4OGQ5NjU2MzVkNjNjNTQ5MmUyZTdjZjRlOWVlOTRiYTM5NWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.-eq2jOXZbPrXwpUy4k9arKE2EIHX055WnVrGCbXeuWE)](https://private-user-images.githubusercontent.com/41189281/578813564-899442db-d32b-4334-a3d8-e140902d6fc0.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODA5NzQ3ODQsIm5iZiI6MTc4MDk3NDQ4NCwicGF0aCI6Ii80MTE4OTI4MS81Nzg4MTM1NjQtODk5NDQyZGItZDMyYi00MzM0LWEzZDgtZTE0MDkwMmQ2ZmMwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA2MDklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNjA5VDAzMDgwNFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTFkMTRhOTlmYzA2ZTEwNzI2YmZmODRmNDJjMDc4OGQ5NjU2MzVkNjNjNTQ5MmUyZTdjZjRlOWVlOTRiYTM5NWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.-eq2jOXZbPrXwpUy4k9arKE2EIHX055WnVrGCbXeuWE)Kirby Consent Gate
==================

[](#kirby-consent-gate)

This plugin for [Kirby CMS](https://getkirby.com) automatically detects and blocks external content (iframes, scripts, embeds) from loading until the user gives consent. Fully GDPR compliant.

Unlike traditional consent plugins that require manual tag overrides, this plugin **parses the rendered HTML output** and automatically wraps any external resource in a consent gate - no matter how the content was added (blocks, tags, templates, raw HTML).

This plugin does not use cookies. Consent is stored in the browser's local storage.

> This is the successor to [kirby3-consent-gate](https://github.com/fendinger/kirby3-consent-gate), completely rewritten for modern Kirby versions.

How It Works
------------

[](#how-it-works)

1. **HTML Parser** scans the rendered page for external ``, ``, `` and `` elements
2. **Visual embeds** (iframes, embeds, objects) are replaced with a consent gate UI showing the vendor's logo, name and privacy information
3. **Scripts** (e.g. Google Analytics) are neutralized with `type="text/plain"` and activated on consent
4. **Compound embeds** (e.g. Twitter blockquote + script) are detected as a unit and gated together
5. A **vendor registry** tracks which vendors were detected across all pages and displays them in the consent banner/modal

Features
--------

[](#features)

- Automatic detection of external content - no manual tag overrides needed
- Supports iframes, scripts, embeds and objects
- Compound embed detection (Twitter/X, Instagram)
- Per-vendor consent via banner and modal
- Vendor registry across all pages
- Cookie-free (uses localStorage)
- Standalone CSS or Tailwind CSS support
- Built-in vendor configs with logos for 15+ services
- Vendor allowlist to skip gating for specific vendors
- English and German translations
- Custom vendor configs via `site/config/config.php`

Supported Vendors (built-in)
----------------------------

[](#supported-vendors-built-in)

Vendor KeyNameURL Patterns`bluesky`Bluesky`bsky.app`, `bsky.social``facebook`Facebook`facebook.com`, `fbcdn.net``flickr`Flickr`flickr.com`, `staticflickr.com``github`GitHub`github.com`, `githubusercontent.com``googleanalytics`Google Analytics`googletagmanager.com`, `google-analytics.com``googlemaps`Google Maps`google.*/maps/``instagram`Instagram`instagram.com`, `cdninstagram.com``kaltura`Kaltura`kaltura.com`, `kaltura.org``mastodon`Mastodon`mastodon.social`, `mastodon.online``matomo`Matomo*(self-hosted, add your domain via config)*`openstreetmap`OpenStreetMap`openstreetmap.org`, `osm.org``spotify`Spotify`spotify.com``vimeo`Vimeo`vimeo.com``x`X/Twitter`x.com`, `twitter.com`, `twimg.com``youtube`YouTube`youtube.com`, `youtu.be`, `youtube-nocookie.com`, `ytimg.com`Unknown external sources are automatically gated as `unknown:hostname` (configurable via `gateUnknown`).

Installation
------------

[](#installation)

### Composer

[](#composer)

```
composer require fendinger/kirby-consent-gate

```

### Manual

[](#manual)

Download and copy this repository to `/site/plugins/kirby-consent-gate`.

Configuration
-------------

[](#configuration)

All options are set in `site/config/config.php`:

### Style

[](#style)

Choose between standalone CSS (default) or Tailwind CSS:

```
// Standalone CSS (default) - no dependencies
'fendinger.consent-gate.style' => 'css',

// Tailwind CSS - assumes Tailwind is active in your project
'fendinger.consent-gate.style' => 'tailwind',
```

### Allowlist

[](#allowlist)

Vendors that should never be gated (by vendor key):

```
'fendinger.consent-gate.allowlist' => [
    'youtube',
    'x',
],
```

For unknown vendors, use the `unknown:hostname` format:

```
'fendinger.consent-gate.allowlist' => [
    'unknown:cdn.example.com',
],
```

### Gate Unknown Sources

[](#gate-unknown-sources)

Whether to gate external sources that don't match any known vendor:

```
'fendinger.consent-gate.gateUnknown' => true, // default
```

### Gate Elements

[](#gate-elements)

Which HTML element types to scan:

```
'fendinger.consent-gate.gateElements' => ['iframe', 'script', 'embed', 'object'], // default
```

### Privacy Page

[](#privacy-page)

Slug of the page to link as privacy policy in the consent modal:

```
'fendinger.consent-gate.privacyPage' => 'datenschutz', // default
```

### Custom Vendors

[](#custom-vendors)

Add or override vendor configurations:

```
'fendinger.consent-gate.vendors.tiktok' => [
    'name' => 'TikTok',
    'urlPatterns' => ['tiktok\.com'],
    'compoundPattern' => ']*class="[^"]*tiktok-embed[^"]*"[^>]*>.*?\s*]*src="[^"]*tiktok\.com/embed\.js[^"]*"[^>]*>\s*',
    'logo' => '...',
    'description' => [
        'en' => 'TikTok videos are embedded on our website...',
        'de' => 'Auf unserer Website werden TikTok-Videos eingebunden...',
    ],
    'privacy' => 'https://www.tiktok.com/legal/privacy-policy',
],
```

#### Vendor Config Options

[](#vendor-config-options)

OptionDescription`name`Display name`urlPatterns`Array of regex patterns matched against element URLs`compoundPattern`Optional regex for multi-element embeds (e.g. blockquote + script)`logo`SVG markup (48x48)`description`Array with `en` and `de` keys containing HTML descriptions`privacy`URL to the vendor's privacy policyHow the Parser Works
--------------------

[](#how-the-parser-works)

The plugin hooks into Kirby's `page.render:after` event and processes the HTML in two steps:

1. **Compound embeds** are detected first via regex patterns (e.g. Twitter's `` + `` combo) and wrapped in a gate
2. **Individual elements** are parsed with PHP's `DOMDocument`. For each ``, ``, `` or `` with an external URL:
    - The URL is checked against the site's own domain
    - The matched vendor is checked against the allowlist
    - The URL is matched against vendor `urlPatterns`
    - **Iframes/embeds/objects** are replaced with the gate UI
    - **Scripts** are neutralized with `type="text/plain"` and reactivated via JS on consent

Vendor Registry Updates
-----------------------

[](#vendor-registry-updates)

The vendor registry stays in sync automatically through the following hooks:

- **`page.render:after`** — on every frontend visit, detected vendors for that page are written to the registry
- **`page.create:after`** — newly created pages are rendered immediately so their vendors get registered right away
- **`page.update:after`** — updated pages are re-rendered so their registry entry reflects the latest content
- **`page.changeSlug:after`** — the old page ID is removed from the registry and the page is re-rendered under its new ID
- **`page.delete:after`** — the deleted page's entry is removed from the registry

Because creating, updating or renaming a page triggers a full render inside the Panel request, saving may take slightly longer on very heavy pages.

### Manual crawl

[](#manual-crawl)

If the registry is ever out of sync (e.g. after a bulk content import or after installing the plugin on an existing site), you can trigger a full crawl via:

```
GET /consent-gate/crawl

```

This iterates over all pages, renders each one and returns a JSON summary with the number of rendered pages, any failures and the aggregated list of detected vendors.

Limitations
-----------

[](#limitations)

The parser runs on Kirby's `page.render:after` hook, which only fires when a `Kirby\Cms\Page` is actually rendered. As a result, the following cases are **not** covered:

- **Custom routes** defined in `site/config/config.php` that return HTML directly (without calling `$page->render()` or `site()->visit()`)
- **Plugin routes** that return their own `Response`
- **API / JSON endpoints**
- Any other output that bypasses Kirby's page rendering pipeline

External resources embedded in such responses will **not** be gated automatically. If you use custom routes to deliver HTML, you will need to handle consent for external content there manually.

Support
-------

[](#support)

If you find this plugin useful, you can support the development:

[![Buy Me A Coffee](https://camo.githubusercontent.com/1dea0ad376c70a0cbfde2d09ed3621fa1aa91b4bba6e95ad2d3354f962155b9a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275792532304d6525323041253230436f666665652d737570706f72742d79656c6c6f773f7374796c653d666c61742d737175617265266c6f676f3d6275792d6d652d612d636f66666565)](https://buymeacoffee.com/fendinger)

License
-------

[](#license)

MIT

Author
------

[](#author)

[fendinger.de](https://fendinger.de)

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance89

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

55d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/41189281?v=4)[fendinger](/maintainers/fendinger)[@fendinger](https://github.com/fendinger)

---

Top Contributors

[![fendinger](https://avatars.githubusercontent.com/u/41189281?v=4)](https://github.com/fendinger "fendinger (1 commits)")

---

Tags

cookieembedgdprkirbykirby-pluginprivacyconsentiframe

### Embed Badge

![Health badge](/badges/fendinger-kirby-consent-gate/health.svg)

```
[![Health](https://phpackages.com/badges/fendinger-kirby-consent-gate/health.svg)](https://phpackages.com/packages/fendinger-kirby-consent-gate)
```

###  Alternatives

[statikbe/laravel-cookie-consent

Cookie consent modal for EU

217416.5k](/packages/statikbe-laravel-cookie-consent)[belugadigital/kirby-navigation

Kirby 5 field for hierarchical menus with drag &amp; drop level indentation.

8613.8k](/packages/belugadigital-kirby-navigation)[codingfreaks/cf-cookiemanager

Manage cookies, scripts, and GDPR compliance on your Typo3 website with CodingFreaks Typo3 Cookie Manager. Customize cookie banners, streamline workflow, and enhance user experience. Ensure GDPR compliance and take control of cookie management with our Typo3 cookie management extension. Visit the official Typo3 Documentation page to learn more.

1829.2k](/packages/codingfreaks-cf-cookiemanager)[bramdeleeuw/cookieconsent

GDPR compliant cookie bar and consent checker

1511.6k2](/packages/bramdeleeuw-cookieconsent)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
