FR EN

Server side

The honest boundary

JavaScript cannot read or delete httpOnly cookies. It also cannot stop your server from emitting a Set-Cookie header. The Agreely banner never claims otherwise. If your application emits cookies server-side, handling those cookies is your responsibility, and the banner cannot substitute for that.

The right approach: read the agreely_consent first-party cookie server-side before any processing or before emitting a non-essential Set-Cookie.

The banner emits a first-party cookie named agreely_consent:

  • SameSite=Lax, Secure (on HTTPS), Path=/
  • Max-Age: 183 days by default (symmetric for both accept and refuse)
  • Value: URL-encoded JSON
{
  "v": 1,
  "consentId": "550e8400-e29b-41d4-a716-446655440000",
  "decisions": {
    "analytics": false,
    "marketing": false,
    "functional": false
  },
  "configVersion": 3,
  "ts": 1721390400,
  "locale": "en"
}

The decisions key contains the non-essential purposes declared for your website with the value true (granted) or false (refused or not yet granted). The absence of the cookie means no decision has been made: treat it as a refusal.

<?php
function agrConsentDecision(string $purpose): bool
{
    $raw = $_COOKIE['agreely_consent'] ?? null;
    if ($raw === null) {
        return false; // no decision = refuse
    }
    $data = json_decode(urldecode($raw), true);
    return ($data['decisions'][$purpose] ?? false) === true;
}

// Before emitting an analytics cookie:
if (agrConsentDecision('analytics')) {
    setcookie('_ga_custom', $value, [
        'expires'  => time() + 63072000,
        'path'     => '/',
        'secure'   => true,
        'httponly' => false,
        'samesite' => 'Lax',
    ]);
}

// Before a marketing tracking session:
if (agrConsentDecision('marketing')) {
    // load pixel, tracker, etc.
}
import cookieParser from 'cookie-parser';

function agrConsent(req, purpose) {
  const raw = req.cookies?.agreely_consent;
  if (!raw) return false;
  try {
    const data = JSON.parse(decodeURIComponent(raw));
    return data?.decisions?.[purpose] === true;
  } catch {
    return false;
  }
}

// Express middleware
app.use(cookieParser());

app.get('/track', (req, res) => {
  if (!agrConsent(req, 'analytics')) {
    return res.status(204).end(); // refused: no tracker
  }
  res.cookie('_mytracker', sessionId, {
    maxAge: 63072000 * 1000,
    httpOnly: false,
    secure: true,
    sameSite: 'lax',
  });
  // continue with tracker
});

Best practices

  • Treat the absence of the cookie as a refusal. A user whose cookie has expired or who has not yet interacted with the banner has not consented.
  • Do not cache the consent decision in session memory. Read the cookie on each relevant request, because the visitor may withdraw consent in another tab.
  • Do not create tracking httpOnly session cookies before the decision. An httpOnly strictly-necessary cookie (e.g., an authentication session cookie) is fine; a httpOnly analytics or marketing cookie emitted before consent is a non-conformance.

Law 25 note. Article 14 of Law 25 requires consent to be manifest, free, and informed, and requested for each purpose. Reading the agreely_consent cookie server-side is the correct way to honor the visitor's decision for your server-emitted cookies. Agreely helps you document and demonstrate your approach; you remain responsible for the legal validity of consent for your own purposes.