Guide · June 17, 2026

Laravel cookie consent for PDPL: middleware, block scripts, store state

Guide to cookie consent for Laravel/PHP under PDPL: middleware, block scripts, store state and proof of consent.

consent.vn Editorial7 min read

Quick answer

If you integrate cookie consent for Laravel/PHP under the PDPL, clearly separate necessary cookies from tracking cookies, block scripts before the user gives consent, then store the consent state along with the timestamp, banner version, and proof of consent so you can demonstrate compliance.

What is Laravel cookie consent under the PDPL and why does it need to be done right?

You need to get it right because cookie consent is not just a UI banner; it is part of the mechanism for collecting and demonstrating consent when a website/app uses cookies or trackers for analytics, ads, retargeting, heatmaps, or A/B testing. Under the Personal Data Protection Law (Law 91/2025/QH15), expected to take effect 01/01/2026 and replacing Decree 13/2023/ND-CP, businesses must comply with the prescribed principles of processing personal data, especially where cookies can identify or be linked to an individual.

In Vietnam in practice, many Laravel/PHP teams only show an “Accept all” banner but still load Google Analytics, Meta Pixel, and Hotjar right from the top of the page. This undermines consent because scripts have already run before any choice is made. If there is an incident or an inspection, the business needs to prove: the user was informed, had a choice, and the system honored that choice.

How should you design cookie consent integration in Laravel/PHP?

The safest approach is to split it into 3 layers: display the banner, block scripts by category, and store the consent state on the server. With Laravel, middleware is a sensible place to decide whether to render or inject scripts on a per-request basis.

A simple model:

  • Strictly necessary: login cookies, CSRF, session, load balancer. Usually no consent is required, but they should still be disclosed.
  • Analytics/Performance: only enable after the user consents.
  • Marketing/Ads: only enable after separate user consent.
  • Preference: language, UI; depending on the case, may require consent or simply be a user setting.
ItemRecommended in LaravelReason
Cookie bannerShow before loading trackersPrevent scripts from running early
MiddlewareCheck consent state per requestBlock render/inject scripts
Session/Cookie to store stateStore consent categories, timestamp, versionProve the choice was recorded
Proof logsStore accept/reject/update eventsSupport audit/DSAR
CMP/consent platformDepending on scale, use when many scriptsEasier management, fewer errors

How should middleware in Laravel block scripts?

In Laravel, middleware doesn’t necessarily have to “remove” prewritten scripts; it can decide which variables are passed into the view, or whether to allow injecting tracker tags. For example, you can set a flag consent.analytics = true after reading a cookie/session and only render Google Analytics if that flag is valid.

A practical approach:

  1. Create a cookie_consent cookie or session to store the grouped consent state.
  2. Middleware reads this state on every request.
  3. The view only renders <script> for analytics/marketing when the corresponding consent is true.
  4. If the user refuses, still retain the necessary cookies for operations.

A short Laravel logic example:

// App\Http\Middleware\LoadConsentState.php
public function handle($request, Closure $next)
{
    $consent = json_decode($request->cookie('cookie_consent', '{}'), true);
    view()->share('consentAnalytics', $consent['analytics'] ?? false);
    view()->share('consentMarketing', $consent['marketing'] ?? false);
    return $next($request);
}

In Blade:

@if($consentAnalytics)
<script src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);} gtag('js', new Date());
  gtag('config', 'GA_MEASUREMENT_ID');
</script>
@endif

The important point is that external scripts should not be loaded before valid consent if their purpose is analytics or marketing.

How do you store the consent state to prove consent?

Storing just “Accepted” is not enough. At a minimum, you should store:

  • user_id or internal visitor_id if available
  • the consent categories selected
  • the time of consent/decline
  • the banner/policy version at that time
  • source: web, app, API
  • IP or a light fingerprint if internal policy permits and in line with regulations

Sample data stored in the database:

{
  "visitor_id": "v_123456",
  "analytics": true,
  "marketing": false,
  "necessary": true,
  "banner_version": "2026-01",
  "policy_version": "2026-01-15",
  "consented_at": "2026-03-10T08:30:00+07:00",
  "source": "web"
}

For an SME system, a single consent_events table is enough to get started. For a larger product, split out consent_profiles and consent_audit_logs to track changes over time. When users change their minds, you must update the new state and stop the corresponding scripts from the next request.

What should you watch out for when using Google Tag Manager, Meta Pixel, hotjar?

These tools often pull in many third-party trackers. The issue is not the tool’s name, but what obligations it triggers under the regulations: inform, obtain consent, store proof, and allow withdrawal of consent. Configure everything “default off” for any non-essential trackers, then enable only after consent.

With Laravel/PHP, avoid common mistakes:

  • placing the GTM script in <head> before the banner
  • using a frontend plugin without syncing server-side state
  • storing consent only in frontend localStorage with no server log
  • not allowing users to change their choice after they have consented

If you process user data at scale or have cross-border transfers, review the entire flow with counsel because the PDPL and its implementing decrees may impose additional specific obligations.

  1. Classify scripts:

    list all cookies/scripts into necessary, analytics, marketing, preference.

  2. Design the consent state:

    create a structure to store the state in cookie/session and a `consent_events` table in the database.

  3. Write middleware:

    read consent state on each request and share variables to Blade/React/Vue.

  4. Block scripts by default:

    render trackers conditionally with `@if` or lazy-load after the user consents.

  5. Log proof:

    store timestamp, banner version, and accept/reject/update actions for inspection.

  6. Allow changes:

    add a “Manage cookies” button in the footer so users can withdraw or adjust consent.

What should a cookie consent template for Laravel/PHP look like?

Below is a minimal template you can use right away for the banner and internal messaging. You can adjust the wording to fit your product, but keep the purpose clear and the right to refuse.

Banner sample:

We use necessary cookies to operate the website and analytics/marketing cookies to improve your experience. You can accept, refuse, or customize your choices. See our Cookie Policy for details.

Buttons: Accept all | Reject non-essential | Customize

Sample state fields:

Field Example Purpose
visitor_id v_123456 Identify the consent record
analytics true/false Toggle analytics trackers
marketing true/false Toggle advertising trackers
banner_version 2026-01 Prove the version shown
consented_at 2026-03-10 08:30 Time of consent

FAQ about Laravel cookie consent under the PDPL

Yes, if you want to block scripts based on consent consistently across requests. Middleware helps check the consent state and only render trackers when allowed under the regulations.
You should not rely solely on localStorage. Store a server-side record as well to provide proof of consent and support audits, changes of mind, or incident reconciliation.
If analytics has not been consented to by the user, the default should be not to load the script. The safest way is to inject only after valid consent.
If a personal data breach occurs, the business must notify within 72 hours of detection, as required.

If you need to implement a banner, store proof of consent, or DSAR flows for Laravel/PHP, consent.vn can help you design this in an audit-friendly and maintainable way.

Source: the Personal Data Protection Law (Law 91/2025/QH15); Decree 13/2023/ND-CP; Ministry of Public Security — Department of Cybersecurity and High-Tech Crime Prevention (A05): https://thuvienphapluat.vn, https://bocongan.gov.vn

Get started — set up in 5 minutes.

Need help with PDPL compliance?

Get started