Fundusze Europejskie Województwo Łódzkie Unia Europejska
WooCommerce

Consent Mode v2 without losing the visits that did consent

In short

A refusal cannot be recovered, and no first-party method changes that. What first-party capture fixes is the opposite problem: most setups also lose visitors who did consent, because on the first ad visit the consent cookie does not exist yet when the server checks it — and that is the visit carrying the ad id.

Two signals were added to the existing ones: ad_user_data and ad_personalization. Google's documentation states that for traffic from the European Economic Area you must collect consent for the use of personal data and pass those signals, and that sites maintaining their own banner have to upgrade it to send them. Without the signals, ads personalisation capability is lost.

That is a requirement about what you tell Google. It says nothing about what you are allowed to record on your own infrastructure, which is a separate question with a separate answer, and conflating the two is how measurement projects acquire legal risk they did not need.

What you can measure after a refusal

Nothing about that visitor. No touchpoint, no chain, no attribution.

This deserves stating plainly because the market around it is not plain. A visitor who declines the advertising category has declined it, and there is no first-party trick that converts a refusal into a lawful record. Any vendor whose pitch is recovering those conversions is selling either a misunderstanding of the rules or a liability with a dashboard attached.

What a first-party approach genuinely changes is the other side: not losing the visitors who did consent. Most setups lose a large share of those, and for reasons that have nothing to do with the law.

The gap that loses your consented visits

Here is the failure mode, and it is close to universal in server-side setups.

A visitor arrives from an ad. The URL carries utm_content, gclid, whatever your tagging puts there. The consent banner appears. At this moment the consent cookie does not exist — the question has been asked and not answered.

Server-side capture runs early in the request. It checks consent, finds none, and correctly skips. The visitor then accepts the banner. But the request that carried the campaign parameters is over, and the next page view has a clean URL.

The visit that named the campaign is gone, and consent was given.

The fix is not more server-side code. It is a small client-side listener that fires on acceptance and posts the parameters — still sitting in the address bar — to an endpoint that captures with consent now verified. In our plugin that endpoint is loyalz_tp_capture, registered for logged-out visitors as well as logged-in ones, which is the detail that matters since almost nobody is logged in on first visit.

A server-side implementation without this loses its first touchpoint on every consented ad visit. The first touchpoint is the one carrying the ad id.

FieldSourceWhy it is there
ad_idutm_contentTies the visit to one creative, not just a campaign
utm_*URLSource, medium, campaign, term
gclid, fbclid, ttclid, msclkidURLClick ids from Google, Meta, TikTok, Microsoft
referrer, landing_urlRequestHost and path only, not the query string
tsServerISO-8601, UTC

Stored in a first-party cookie set httponly, secure and SameSite=Lax, holding at most 20 touchpoints for 90 days, and moved onto the order at checkout.

Two properties are worth separating from the marketing of this category. The visitor id is 128 bits from random_bytes — it is not a hash of an email, an IP or a device fingerprint, so it identifies a browser and nothing else. And the funnel event is gated twice: no consent, no event; no prior visitor id, no event either. A visitor who was never tracked because they had not consented does not retroactively acquire a funnel when they add something to a basket.

Traffic with no campaign markers is still classified — direct, organic or referral, derived from the referrer — so those channels appear in the path instead of being a blank. Internal navigation is skipped, so a browsing session does not manufacture twenty touchpoints out of page views.

Our own implementation contains a decision worth surfacing rather than burying, because every implementation in this category makes some version of it.

When a visitor submits a soft conversion — a newsletter form, a lead form — the plugin treats that submission as consent and creates a visitor id even where no banner signal exists. The reasoning is that someone handing over an email address has engaged deliberately.

That reasoning is not obviously wrong and it is not obviously right. A person subscribing to a newsletter has consented to a newsletter. Whether that also constitutes consent to advertising measurement is a different question, it depends on what your banner and privacy notice actually say, and it is a question for your counsel rather than for your plugin author or for this article.

We are flagging it because the alternative — writing a piece about consent that presents our own implementation as settled — is the kind of thing that reads well until someone reads the code. If you run a consent-gated first-party setup of any kind, find the equivalent decision in yours. There will be one.

For the mechanics of what breaks in WooCommerce independently of consent, see why conversion tracking breaks and how to test it, and the wider cluster under measurement for WooCommerce.

Common questions

Can I track users who refuse consent?

No. There is no touchpoint, no chain and no attribution for that visitor, and that is the correct outcome rather than a limitation to engineer around. The measurable ceiling on any setup is your consented traffic share, and the lever that moves it is banner design.

Does server-side tracking bypass consent requirements?

No. Where the code runs has no bearing on whether you have a lawful basis to record something. Server-side capture solves reliability problems — blockers, dropped pages, broken scripts — not consent ones, and any pitch that blurs those two is worth reading twice.

What is the consent-timing gap?

On the first visit from an ad the banner has not been answered yet, so a server-side check finds no consent and correctly skips capture. By the time the visitor accepts, the request carrying the campaign parameters is over. Without a listener that re-submits those parameters on acceptance, every consented first visit loses the touchpoint naming the ad.

Is a first-party visitor id personal data?

That depends on what it is derived from and what it is joined to, which is why the derivation matters. Ours is 128 random bits, not a hash of an email or an IP, so on its own it identifies a browser. Whether your setup's id has the same property is worth checking rather than assuming.

PS

Paweł Strzelecki

Head of Growth, Loyalz · acquisition and retention mechanics

See it on your data

Loyalz joins ad spend to settled order lines, so POAS is a column rather than a spreadsheet you rebuild every month.

Book a demo