> ## Documentation Index
> Fetch the complete documentation index at: https://docs.katla.app/llms.txt
> Use this file to discover all available pages before exploring further.

# WordPress & WooCommerce

> Install the Katla plugin to load consent, block non-consented scripts server-side, and render your generated policies in WordPress.

The [Katla Cookie Consent plugin](https://github.com/katla-app/wordpress) brings GDPR, CCPA/CPRA and DMA compliance to WordPress and WooCommerce. It loads Katla's consent script, blocks non-consented scripts and embeds **on the server**, and renders the cookie and privacy policies Katla generates for you.

## Prerequisites

|             |                                         |
| ----------- | --------------------------------------- |
| WordPress   | 6.3+                                    |
| PHP         | 7.4+                                    |
| WooCommerce | 7.0+ (optional)                         |
| Katla       | A site with at least one completed scan |

If you haven't added a domain yet, start with the [quickstart](/quickstart).

## Install

Copy the plugin into `wp-content/plugins/katla-consent`, activate it, then set your Site ID:

```bash theme={null}
wp plugin activate katla-consent
wp katla site-id 00000000-0000-0000-0000-000000000000
wp katla verify
```

Or paste the Site ID into **Settings → Katla Consent**.

<Note>
  `wp katla verify` confirms the Site ID resolves against Katla. If it fails, the site has
  probably not completed a scan yet — the plugin needs cookie data to render policies.
</Note>

## Modes

<Tabs>
  <Tab title="Hosted widget">
    The default. Loads `https://dist.katla.app/{siteId}.js`, and Katla renders the banner
    and preferences dialog styled from your dashboard. Nothing to build.
  </Tab>

  <Tab title="Built-in banner">
    Loads the same script with `?headless=true` — the cookie guard and `window.KatlaConsent`
    only, no hosted UI. The plugin then renders its own banner and preferences dialog from
    plain DOM, translated through WordPress and styled with CSS custom properties.
  </Tab>

  <Tab title="Bring your own UI">
    Headless, and the plugin renders nothing. Build your own interface against
    `window.KatlaConsent` and the `katla:consent` event. Anything marked
    `data-katla-open-settings` fires a `katla:open-settings` event for your UI to handle.
  </Tab>
</Tabs>

## Blocks and shortcodes

Every shortcode has a matching Gutenberg block.

| Shortcode                                               | Renders                                       |
| ------------------------------------------------------- | --------------------------------------------- |
| `[katla_policy]`                                        | Full cookie + privacy policy                  |
| `[katla_policy format="cookie"]`                        | Cookie policy only                            |
| `[katla_policy format="table"]`                         | Cookie tables only                            |
| `[katla_cookie_table category="analytics"]`             | Scanned cookies, grouped by category          |
| `[katla_cookie_settings]`                               | Button or link that reopens the preferences   |
| `[katla_block category="marketing"]…[/katla_block]`     | Holds back the enclosed scripts and iframes   |
| `[katla_consent category="analytics"]…[/katla_consent]` | Shows the enclosed content only while allowed |

`[katla_policy]` renders on the server by default, so the policy is part of the page HTML and indexable by search engines. Pass `render="client"` to use Katla's hosted `policy.js` instead.

## Blocking scripts

This is the part worth understanding properly.

Katla's cookie guard stops cookies from being **written**. It does not stop a tracker from loading in the first place. For scripts that phone home regardless of whether they can set a cookie, gate the script itself — on the **Blocking** tab, or from code:

```php theme={null}
add_action( 'wp_enqueue_scripts', function () {
	katla_block_script( 'google-analytics', 'analytics' );
	katla_block_script( 'facebook-pixel', 'marketing' );
}, 20 );
```

A blocked handle is rewritten to `<script type="text/plain" data-katla-src="…" data-katla-category="analytics">`. Inline scripts attached to the same handle via `wp_add_inline_script` are neutralised alongside it and replayed **in source order** once the category is allowed, so tag configuration is never lost.

You can also match on URL fragments rather than handles, which is useful for scripts a theme or plugin injects without registering.

## WooCommerce

The plugin declares compatibility with **HPOS** (`custom_order_tables`) and the **cart/checkout blocks**.

Store-critical cookies bypass the cookie guard automatically — `woocommerce_cart_hash`, `woocommerce_items_in_cart`, `wp_woocommerce_session_*`, `wc_cart_hash_*`, `wc_fragments_*`, `store_notice*` and friends. Store-critical script handles (`wc-cart-fragments`, `wc-checkout`, `wc-blocks-checkout`) are stripped from the blocked list, so a stray blocking rule can't break checkout.

<Note>
  Order attribution cookies (`sbjs_*`) are deliberately **not** allowlisted — they are
  marketing cookies. To stop them being set at all, gate the `wc-order-attribution` handle
  on the Blocking tab.
</Note>

Optionally, the plugin appends a cookie settings link to the checkout and registration privacy notice, and to the My Account dashboard.

## JavaScript API

`window.KatlaConsent` is Katla's own API — see the [JavaScript API reference](/javascript-api). The plugin adds:

```js theme={null}
window.katlaWP.openSettings();             // Open the preferences dialog
window.katlaWP.isAllowed('analytics');     // boolean
window.katlaWP.getAllowedCategories();     // string[]
window.katlaWP.allowCategory('marketing'); // Add one category to the current consent
window.katlaWP.activateBlocked();          // Re-scan the DOM for blocked nodes
window.katlaWP.config;                     // The server-rendered configuration
```

It dispatches the SDK-compatible event on every change:

```js theme={null}
window.addEventListener('katla:consent', (event) => {
  // { functional: true, analytics: true, marketing: false, …, type: 'partial' }
  console.log(event.detail);
});
```

<Note>
  The plugin takes ownership of `KatlaConsent.onConsentChange` as a subscriber list, so
  assigning to it — as `@katla.app/sdk`'s `ConsentBridge` does — *adds* a listener rather
  than replacing the plugin's.
</Note>

## Markup contract

Anything the plugin holds back is marked up so you can style or extend it:

```html theme={null}
<!-- A blocked script -->
<script type="text/plain" data-katla-src="…" data-katla-category="analytics"></script>

<!-- A blocked embed -->
<div class="katla-blocked" data-katla-blocked="marketing">
  <div class="katla-blocked__notice">…<button data-katla-allow="marketing">…</button></div>
  <iframe hidden data-katla-embed="1" data-katla-src="…"></iframe>
</div>

<!-- Content shown only while a category is allowed -->
<div class="katla-consent-gate" data-katla-requires="analytics" hidden>…</div>
```

## Customizing

The plugin exposes PHP helpers and a set of filters. The most useful ones:

| Filter                      | Purpose                                                    |
| --------------------------- | ---------------------------------------------------------- |
| `katla_blocked_handles`     | Script handles gated behind consent                        |
| `katla_blocked_patterns`    | Script URL fragments gated behind consent                  |
| `katla_blocked_placeholder` | Markup shown in place of blocked content                   |
| `katla_cookie_allowlist`    | Cookie names that bypass the guard (trailing `*` = prefix) |
| `katla_translations`        | Banner and placeholder strings                             |
| `katla_banner_css_vars`     | CSS custom properties for the built-in banner              |
| `katla_categories`          | Category labels and descriptions                           |
| `katla_should_load`         | Whether the consent script loads on this request           |

Restyling the built-in banner to match your theme:

```php theme={null}
add_filter( 'katla_banner_css_vars', function () {
	return array(
		'katla-primary' => '#111111',
		'katla-radius'  => '0px',
		'katla-font'    => 'var(--wp--preset--font-family--body)',
	);
} );
```

PHP helpers are available for building your own templates:

```php theme={null}
katla_is_active();                      // bool
katla_block_script( $handle, $cat );    // Gate an enqueued script
katla_get_cookies( $locale );           // Scanned cookies by category
katla_get_policy_html( $format );       // Generated policy as HTML
katla_settings_link( $label, $tag );    // Markup for a preferences link
katla_blocked_placeholder( $html, $c ); // Wrap markup in a consent placeholder
```

The complete list of filters and actions is in the [plugin README](https://github.com/katla-app/wordpress#hooks).

## WP-CLI

```bash theme={null}
wp katla status                       # Configuration and connection summary
wp katla site-id <uuid>               # Get or set the Site ID
wp katla verify                       # Confirm the Site ID resolves
wp katla cookies --category=marketing # List scanned cookies
wp katla policy --format=cookie --as=html
wp katla flush                        # Clear cached Katla responses
```

## Caching

Cookie and policy responses are cached in transients — 12 hours by default, configurable on the **Policies** tab, or `0` to disable. The cache is cleared when settings are saved, from the Tools tab, via `wp katla flush`, and on deactivation.

## Compliance notes

**Load order matters.** The cookie guard must run before any script that sets cookies. Keep the placement on *Head*, and exclude `dist.katla.app` from JS deferral or combination in optimisation plugins such as WP Rocket or Autoptimize. Deferring the guard is the single most common way a WordPress install ends up non-compliant while looking fine.

**Equal prominence.** In the built-in banner, "Reject all" and "Accept all" use identical size, padding and weight, so neither is the nudged choice. This is a [DMA](/dma) requirement and a growing expectation under GDPR enforcement.

**Hide from roles is for development.** Users in those roles see no banner and no consent record is created for them. Don't leave it enabled for a role that real visitors have.

## Next steps

<CardGroup cols={2}>
  <Card title="Google Consent Mode" icon="bar-chart-3" href="/google-consent-mode">
    Signal consent to Google Analytics and Ads.
  </Card>

  <Card title="JavaScript API" icon="code" href="/javascript-api">
    The full `window.KatlaConsent` surface.
  </Card>

  <Card title="Policy embed" icon="file-text" href="/policy-embed">
    Other ways to publish your generated policies.
  </Card>

  <Card title="Plugin source" icon="github" href="https://github.com/katla-app/wordpress">
    Issues, releases, and the full hook reference.
  </Card>
</CardGroup>
