WordPress Cookie Consent Without a Plugin: The Three Hooks That Do the Work
A WordPress site needs cookie consent, and the usual answer is a plugin. The plugin is the shortcut, not the requirement. WordPress has the hooks to do the work itself: three of them, in the right order, block the cookies until the visitor chooses, and the consent record is a row in the database. The plugin saves time. The hooks teach you what the plugin is doing.
The plugin is the shortcut, not the requirement
A consent plugin does four things: it shows the banner, it blocks the scripts until consent, it records the choice, and it lets the visitor change it. Three of those four are simple, and the fourth is a database row. The banner is HTML and CSS. The blocking is a filter on the script tags. The record is an option or a custom table. The plugin wraps those four things in a settings page, and the settings page is what you are paying for, in weight and in complexity.
The weight matters. A consent plugin loads its scripts on every page, and the scripts run before the content, because the banner has to appear before the tracking does. The third-party script audit post is the same problem from the script side: the scripts that load before consent are the ones that set the cookies, and the audit is the list of them. A plugin that loads its own scripts before consent is doing the thing it exists to prevent, just with its own scripts.
The hooks are the alternative, and they are already in WordPress. The consent API, wp-consent-api, provides the functions to check and set consent state, and the consent API post explains how it works: the API is the standard, and the plugins that use it interoperate. The three hooks below use it, and they do the work without a plugin.
The three hooks, and what each one blocks
First, script_loader_tag, which filters every script tag WordPress prints. The filter checks the consent state for the script's category, and if consent is refused, it changes the script type to text/plain, so the browser does not execute it. The analytics script, the marketing script, and the embed script all go through this filter, and the filter is the gate.
Second, wp_enqueue_scripts, which controls which scripts are enqueued at all. The scripts that need consent are enqueued with a consent check, and the ones that do not need it, the functional scripts that make the site work, are enqueued normally. The distinction is the point: functional cookies do not need consent, and the ePrivacy Directive is clear that strictly necessary cookies are exempt. The GPC signal post is the same distinction from the visitor side: the signal is a preference, and the site has to honour it.
Third, the consent API itself: wp_set_consent and wp_has_consent, which record and check the state. The banner sets the state when the visitor chooses, and the hooks read it when the scripts load. The state lives in a cookie, and the cookie is set by the banner, not by the tracking. The three hooks together are the consent system, and they are about fifty lines of code in a child theme or a small custom plugin.
The consent record you still have to keep
The hooks do not keep the record. The record is the proof, and Article 7 of the GDPR puts the burden of proof on the site: the site has to demonstrate that consent was given, when, and for what. The record is a row in the database with the timestamp, the purposes, the banner version, and a visitor identifier that is not itself personal data. The hooks set the state. The record keeps the proof.
The record also has to support withdrawal. When the visitor changes their mind, the hooks have to re-block the scripts, and the record has to show the change. The consent renewal post is the same requirement from the redesign side: a new banner is a new choice, and the old record does not cover it.
Frequently asked questions
Can WordPress handle cookie consent without a plugin?
Yes. Three hooks do the work: script_loader_tag to block scripts until consent, wp_enqueue_scripts to control which scripts load, and the wp-consent-api to record and check the state. The plugin is the shortcut, not the requirement.
What is the WordPress consent API?
wp-consent-api is the standard WordPress provides for checking and setting consent state, with functions like wp_set_consent and wp_has_consent. Plugins that use it interoperate, and the hooks in this post use it directly.
Do functional cookies need consent in WordPress?
No. The ePrivacy Directive exempts cookies that are strictly necessary for the site to work. The distinction matters: functional scripts load normally, and analytics and marketing scripts wait for consent.
Do I still need a consent record if I build it with hooks?
Yes. The hooks set the state, but the record is the proof. Article 7 of the GDPR puts the burden of proof on the site, so keep a row with the timestamp, the purposes, the banner version, and a visitor identifier.