WordPress Consent Logs: What to Record When a Visitor Changes Their Mind
A visitor accepts analytics cookies on Monday, withdraws on Friday, and the site keeps the analytics data from Tuesday to Thursday. The banner state says refused. The database says the data is still there. The log is the only thing that connects the two, and the log is the piece most WordPress sites never build.
Consent is a record, not a banner state
The banner shows the current state: accepted, refused, or not yet chosen. The record shows the history: what the visitor chose, when they chose it, and what changed. The regulator asks for the history, not the state, because the question is whether the data collected on Tuesday was collected with consent, and the banner on Friday cannot answer that. Only the log can.
Article 7 of the GDPR puts the burden of proof on the controller, and the proof is the record. A WordPress site that cannot show when consent was given, for which purposes, and to which version of the banner has no proof, and the banner state is not proof. The comment cookies post is the same principle at small scale: the comment form sets three cookies, and the checkbox is the consent for them, and the record is the proof that the box was checked.
The log belongs in the database, not in the analytics tool, because the analytics tool is the thing the consent controls. A log inside the analytics platform is a log that disappears when consent is withdrawn, which is exactly when it is needed most. Keep it in WordPress, in a custom table or as post meta, where the withdrawal cannot delete it.
The four fields the log has to hold
First, the timestamp, to the second, of every choice and every change. Second, the purposes: which categories the visitor accepted and which they refused, by name, not by a single accept-all flag. Third, the banner version: which text the visitor saw, because the consent is only valid for the text that was shown. Fourth, a visitor identifier that is not itself personal data: a hash, not an email address, not an IP address.
The identifier is the field most sites get wrong. An IP address is personal data under the GDPR, and logging it as the identifier creates a new processing activity that itself needs a basis. A hash of the identifier, salted and stored without the original, identifies the visitor well enough for the record and does not itself identify them. The admin bar cookies post is the same care applied to the dashboard: the cookies the admin bar sets are the ones the site forgets, and the log is the place they get remembered.
The purposes have to be specific. A log that says the visitor accepted is useless. A log that says the visitor accepted analytics and refused marketing, at a timestamp, to banner version 3, is proof. The specificity is the point, and it is the reason the log has four fields, not one.
The withdrawal test that catches the gaps
Test the log the way the regulator will: accept on Monday, browse, withdraw on Friday, and check three things. Did the analytics stop when the withdrawal happened, or did it keep firing? Did the data collected between Monday and Friday stay, with the consent record that covers it? And does the log show the withdrawal, with a timestamp, as a separate entry from the acceptance?
The most common gap is the first one: the scripts keep firing after withdrawal, because the consent state changed in the banner but the scripts were already loaded and never checked again. The fix is to re-check the consent state on every page load, and to unload the scripts when the state changes. The Planet49 post is the same principle from the acceptance side: the choice has to be active, and the active choice has to be enforced, not just recorded.
Frequently asked questions
What should a WordPress consent log record?
Four fields: the timestamp of every choice and change, the purposes accepted and refused by name, the banner version the visitor saw, and a visitor identifier that is not itself personal data, such as a hash. A log that says only that the visitor accepted is useless.
Where should consent logs be stored in WordPress?
In the database, in a custom table or as post meta, not in the analytics tool. The analytics tool is the thing consent controls, and a log inside it disappears when consent is withdrawn, which is exactly when it is needed most.
Can I use an IP address as the visitor identifier in a consent log?
No, not without a legal basis of its own. An IP address is personal data under the GDPR. Use a salted hash instead, stored without the original, which identifies the visitor well enough for the record without identifying them.
How do I test whether withdrawal actually stops tracking?
Accept on Monday, browse, withdraw on Friday, and check three things: did the analytics stop when the withdrawal happened, did the data from Monday to Friday stay with its consent record, and does the log show the withdrawal as a separate entry with a timestamp?