Kjeks — core plugin
The consent engine for WordPress: categories, prior blocking, the banner, and the tracker inventory. Single-site or multisite.
101 Getting started
Install & activate
Download the latestkjeks.zip, then in WordPress go to Plugins → Add New → Upload Plugin and upload it.
- Single site: activate it from Plugins. Admin lives under Settings → Cookie Consent.
- Multisite: the plugin declares
Network: true—Network Activate it. Admin lives underNetwork Admin → Settings → Cookie Consent.
Kjeks then updates itself from GitHub releases viaplugin-update-checker — new versions appear on your Plugins screen like any other update.
Show the banner & preferences
The consent banner renders automatically in the site footer. To let visitors reopen their choices or publish a cookie table, drop in a block or shortcode:
| Purpose | Block | Shortcode |
|---|---|---|
| Reopen the consent banner | kjeks/preferences | [kjeks_preferences] |
| Cookie declaration table | kjeks/cookie-declaration | [kjeks_cookie_declaration] |
Set your content
On the Cookie Consent admin page you set the banner heading and body, your privacy-policy URL, and an accent colour. These are stored once and resolved per site.
The consent categories
| Slug | Default | Meaning |
|---|---|---|
necessary | Always on | Essential; cannot be switched off. |
preferences | Denied | Remembers choices like language or layout. |
analytics | Denied | Measurement and statistics. |
marketing | Denied | Advertising and cross-site tracking. |
Everything except necessary is denied until the visitor opts in. You can add categories with the kjeks_categories filter (see 301), but every non-necessary category is always optional.
kjeks_honor_gpc filter). Browser features that hide cookie notices (Brave Shields, uBlock cookie-notice lists) can also remove it.201 Consent & integrations
Register an integration
Kjeks fires the kjeks_register_integrations action oninit (priority 20). Register your trackers inside it withkjeks_register_integration( $id, $args ) — Kjeks then holds those scripts back until the matching category is granted.
add_action( 'kjeks_register_integrations', function () {
kjeks_register_integration( 'matomo', [
'category' => 'analytics',
'label' => 'Matomo',
'handles' => [ 'matomo-tracker' ],
'src_scripts' => [
'https://cdn.example.com/matomo.js',
[
'src' => 'https://cdn.example.com/extra.js',
'attrs' => [ 'data-site' => '7' ],
],
],
'inline' => [ 'console.log( "loaded after consent" );' ],
] );
} );Integration arguments
| Key | Type | Description |
|---|---|---|
category | string | One of preferences, analytics, marketing. Unknown or necessary falls back to marketing. |
label | string | Human-readable name shown in the cookie declaration. |
handles | string[] | Registered script handles to gate (blocks an already-enqueued script until consent). |
src_scripts | array | External scripts to inject after consent. A plain URL string, or { src, attrs } to add attributes. |
inline | string[] | Inline JS snippets to run after consent. |
Helper functions
Prefer a one-liner? These wrap the same machinery:
| Function | Use |
|---|---|
kjeks_enqueue_script( $handle, $src, $category, $deps = [] ) | Enqueue a script that loads only after the category is granted. |
kjeks_add_inline_script( $category, $code, $id = '' ) | Run inline JS gated by a category. |
kjeks_embed( $src, $category, $args = [] ) | Return consent-gated embed markup (iframes, pixels). |
kjeks_is_granted( $category ) | Boolean check for server-side branching. |
kjeks_preferences_link( $label = '', $display = true ) | Output/return a link that reopens the banner. |
// Enqueue a script that only loads after a category is granted.
kjeks_enqueue_script( 'my-analytics', 'https://cdn.example.com/a.js', 'analytics' );
// Add inline JS gated by a category.
kjeks_add_inline_script( 'marketing', 'window.startPixel();' );
// Render a consent-gated embed (e.g. a YouTube iframe).
echo kjeks_embed( 'https://www.youtube.com/embed/VIDEO_ID', 'marketing' );
// Branch your own PHP on a granted category.
if ( kjeks_is_granted( 'analytics' ) ) {
// …
}
// Output a "Cookie preferences" link that reopens the banner.
kjeks_preferences_link( 'Cookie preferences' );Consent on the front end
The visitor's choice is stored in a cookie and localStorage under the key kjeks_consent, with a six-month lifetime. When consent changes, Kjeks dispatches events you (and add-ons) can listen for:
window.addEventListener( 'kjeks:granted', () => {
// Fired when the visitor grants (or updates) consent.
} );
window.addEventListener( 'kjeks:withdrawn', () => {
// Fired when the visitor withdraws consent.
} );sites list applies to the whole network; otherwise it applies only to the listed blog IDs.301 Hooks, REST & CLI
Filters
| Filter | Default | Purpose |
|---|---|---|
kjeks_categories | — | Add or modify category definitions. |
kjeks_privacy_url | Policy URL | Override the resolved privacy-policy URL (receives blog ID). |
kjeks_banner_content | Stored content | Override the resolved banner content (receives blog ID). |
kjeks_honor_gpc | true | Whether to honour the browser's Global Privacy Control signal. |
kjeks_is_granted | — | Override the server-side category-grant check. |
kjeks_server_side_gating | false | Enable conditional server-side gating of output. |
kjeks_embed_html | — | Modify consent-gated embed markup. |
WP-CLI
wp kjeks scan-config
Generate a scanner config from the sites and paths WordPress knows about.
wp kjeks scan-config [--paths=<paths>] [--output=<file>] [--include=<ids>]Outputs { sites: [ { url, blog_id, policy_version, paths } ] } — feed it straight to the scanner.
wp kjeks import
Import reviewed scanner observations back into the tracker inventory.
wp kjeks import <file> [--blog_id=<id>]The file accepts either shape:
# A single site
{
"blog_id": 1,
"observations": [ /* … tracker observations … */ ]
}
# Or several sites at once
{
"sites": [
{ "blog_id": 1, "observations": [ /* … */ ] },
{ "blog_id": 2, "observations": [ /* … */ ] }
]
}REST API
All routes live under the kjeks/v1 namespace and require manage_network on multisite, or manage_options on a single site.
| Method & route | Body / query |
|---|---|
GET /network-config | Returns the current configuration. |
POST /network-config | reviews, remove, add, content, deleteOnUninstall, bannerDefaultVisible. |
GET /scan-config | Optional include and paths (comma-separated). |
POST /import | Required blog_id and observations. |
Options & tracker schema
| Option | Scope | Shape |
|---|---|---|
kjeks_network_trackers | Network | Tracker records keyed by tracker ID. |
kjeks_network_content | Network | { heading, body, privacy_url, accent } |
kjeks_network_settings | Network | { delete_on_uninstall, banner_default_visible } |
kjeks_policy_version | Per site | Integer; bumping it re-prompts visitors. |
Each tracker record carries:
id, name, category, reviewed,provider, purpose, party,storage_type, domain, path,retention, source, documentation_url,first_observed, last_observed, and sites.