pieowl

Consent management with Pieowl

Learn how to hold analytics events and session replays until the user gives consent, then send them with one call. Or hold only session replay with allowReplay().

Pieowl TeamBeginner · 15 min · 8 Oct 2026
Guide · Consent

Pieowl sets no cookies and stores nothing on your visitors' devices, so in many cases you don't need a consent banner for analytics. But some countries have no exemption for analytics, and session replay needs consent everywhere. See Do you need a cookie banner? for when you still need one.

This guide shows you how to use Pieowl's built-in queue to hold all tracking until the user decides. If they accept, everything is sent at once. If they decline, nothing is sent. It also shows how to hold only session replay with allowReplay().

Prerequisites

  • Pieowl installed with the @pieowl/web npm package or the script tag
  • Your Client ID from the Pieowl dashboard

Initialise with disabled: true

Pass disabled: true when you create the Pieowl instance. Every tracking call (track, identify, screenView and session replay chunks) then waits in a queue in memory instead of going to the API.

Script tag

index.html
<script>
  window.pieowl=window.pieowl||function(){(window.pieowl.q=window.pieowl.q||[]).push(arguments)};
  window.pieowl('init', {
    clientId: 'YOUR_CLIENT_ID',
    disabled: true,
  });
</script>
<script src="https://pieowl.com/pieowl.js" defer></script>

With the script tag, call window.pieowl('ready') when the user accepts.

NPM package

pieowl.ts
import { Pieowl } from '@pieowl/web';

export const pieowl = new Pieowl({
  clientId: 'YOUR_CLIENT_ID',
  disabled: true,
});

From now on, any pieowl.track(...) call in your app is queued and not sent.

How you build the banner is up to you. The key part: call pieowl.ready() when the user accepts, and don't call it when they decline.

This example stores the choice in local storage. That key is your own. Pieowl itself never writes to local storage or sets a cookie.

ConsentBanner.tsx
import { pieowl } from './pieowl';

export function ConsentBanner() {
  function handleAccept() {
    localStorage.setItem('consent', 'granted');
    pieowl.ready(); // sends the queue and turns tracking on
    hideBanner();
  }

  function handleDecline() {
    localStorage.setItem('consent', 'denied');
    hideBanner(); // the queue is dropped when the page unloads
  }

  return (
    <div role="dialog" aria-label="Analytics consent">
      <p>
        We use analytics to improve our product. Is it OK if we measure how
        you use the site?
      </p>
      <button type="button" onClick={handleAccept}>Accept</button>
      <button type="button" onClick={handleDecline}>Decline</button>
    </div>
  );
}

Call ready() on consent

pieowl.ready() does two things:

  1. It clears the disabled flag, so all new events are sent right away
  2. It sends the whole queue: every event and replay chunk saved since the page loaded

So you don't lose the events that happened before the user chose. The page view for the page they landed on, and any clicks they made while the banner was open, are all sent the moment they accept.

Handle session replay

Session replay needs consent on its own. When you turn it on in Settings → Site → What Pieowl counts, keep Record only after visitors agree on. It's on by default. Then the recorder doesn't start until you call allowReplay(). Call it together with ready() when the user accepts:

function handleAccept() {
  localStorage.setItem('consent', 'granted');
  pieowl.ready(); // sends the queue and turns tracking on
  pieowl.allowReplay(); // starts session replay
  hideBanner();
}

With the script tag, call window.pieowl('ready') and window.pieowl('allowReplay').

Hold only session replay

If your analytics can run without consent but replay can't, skip disabled: true and call only allowReplay() when the user accepts:

function handleAccept() {
  localStorage.setItem('consent', 'granted');
  pieowl.allowReplay(); // page views and events were already counted
  hideBanner();
}

allowReplay() lasts for the current page only. Pieowl stores nothing in the browser, so call it on every page load where the user has agreed. See Persist consent across page loads.

Handle decline

If the user declines, don't call ready(). The queue lives only in memory. It is thrown away when the tab closes or the user leaves the page. Nothing is sent.

function handleDecline() {
  localStorage.setItem('consent', 'denied');
  // pieowl stays disabled, so nothing is sent
}

Persist consent across page loads

The disabled flag resets on every page load. So check the stored choice when you create the instance, and skip disabled: true if the user already said yes.

pieowl.ts
import { Pieowl } from '@pieowl/web';

const hasConsent = localStorage.getItem('consent') === 'granted';

export const pieowl = new Pieowl({
  clientId: 'YOUR_CLIENT_ID',
  disabled: !hasConsent,
});

if (hasConsent) {
  pieowl.allowReplay();
}

This file reads localStorage, so load it only in the browser. In your banner, only show it when no choice is stored yet:

ConsentBanner.tsx
export function ConsentBanner() {
  const stored = localStorage.getItem('consent');
  if (stored) return null; // already decided, don't show

  // ... render banner
}

Full example

pieowl.ts
import { Pieowl } from '@pieowl/web';

const hasConsent = localStorage.getItem('consent') === 'granted';

export const pieowl = new Pieowl({
  clientId: 'YOUR_CLIENT_ID',
  disabled: !hasConsent,
});

if (hasConsent) {
  pieowl.allowReplay();
}
ConsentBanner.tsx
import { pieowl } from './pieowl';

export function ConsentBanner() {
  if (localStorage.getItem('consent')) return null;

  return (
    <div role="dialog" aria-label="Analytics consent">
      <p>We use analytics to improve our product. Is that OK?</p>
      <button
        type="button"
        onClick={() => {
          localStorage.setItem('consent', 'granted');
          pieowl.ready();
          pieowl.allowReplay();
        }}
      >
        Accept
      </button>
      <button
        type="button"
        onClick={() => {
          localStorage.setItem('consent', 'denied');
        }}
      >
        Decline
      </button>
    </div>
  );
}
Do I need a consent banner for Pieowl?

Often not for analytics alone. Pieowl sets no cookies, stores nothing on your visitors' devices and doesn't store IP addresses. But some countries, like Germany, Poland and Ireland, have no exemption for analytics, and session replay needs consent everywhere. See Do you need a cookie banner? and ask your legal advisor.

Is anything sent if the user declines?

No. If you never call ready(), nothing is sent. The queue lives in memory and is dropped when the page unloads.

What happens to events tracked before the banner appears?

They wait in the queue. If the user accepts, they are all sent. If the user declines, they are dropped.

Does session replay start before consent?

Not with Record only after visitors agree on, which is the default. The recorder starts only when you call allowReplay(). If you turn that setting off, the recorder starts when the page loads and only ready() holds the data back.

Do I need to handle this differently for the script tag vs npm?

No. The disabled option works the same in both. Call pieowl.ready() and pieowl.allowReplay() with npm, or window.pieowl('ready') and window.pieowl('allowReplay') with the script tag.

Your first dashboard in five minutes.

14-day free trial, no card needed. Cloud in the EU. No cookies.