Guide · June 17, 2026

Angular cookie consent for PDPL: service, guard, dynamic script loading

Guide to PDPL-compliant cookie consent for Angular: service, guard, dynamic script loading by consent, with practical examples.

consent.vn Editorial6 min read

Quick answer

If you build an Angular app and use cookies/analytics/ads, separate consent into a central service, gate routes or components based on consent status, and load scripts dynamically only after the user agrees. Under the PDPL, you must manage consent transparently, store evidence of consent, and be able to prove who consented and when.

What is angular cookie consent PDPL and why should Angular apps care?

Angular apps may not handle personal data directly in the UI, but cookies, localStorage, tag managers, chat widgets, heatmaps, analytics, or ads can trigger consent and notice obligations. With the PDPL (the Personal Data Protection Law (Law 91/2025/QH15), expected effective 01/01/2026), businesses must manage consent more clearly than under Decree 13/2023/ND-CP, especially when third parties and data transfers via scripts are involved.

For Vietnamese SMEs, common pitfalls are: a popup with only an “OK” button with no stored proof; Google/Meta scripts loading immediately on page open; or the user has refused but the app still fires tracking events. When the enforcer is the Ministry of Public Security — Department of Cybersecurity and High-Tech Crime Prevention (A05), you will need to demonstrate a compliant process under the regulations, not just “having a banner”.

How should cookie consent be designed in an Angular integration?

The best design is to treat consent as an application state, not just a popup.

You should have three layers:

  • Consent service: store/read consent status, cookie categories, timestamp, notice version.
  • Route or component guard: block areas that only work with consent, e.g., an internal analytics dashboard or features that require third parties.
  • Dynamic script loader: inject scripts only after the user consents, instead of putting them in index.html.
ComponentRolePDPL notes
ConsentServiceManage accept/decline statusMust store proof of consent
CookieBannerComponentDisplay choicesClear accept/decline/customize buttons
GuardGateflows that require consentDo not use to “force consent”; only protect functionality
ScriptLoaderLoad scripts per consentDo not load analytics/ads before consent

How should the consent service in Angular be written?

A minimal ConsentService should read, write, and emit consent change events so other components can react.

Simple example:

export type ConsentState = 'accepted' | 'rejected' | 'custom' | null;

export interface ConsentRecord {
  state: ConsentState;
  updatedAt: string;
  version: string;
}

@Injectable({ providedIn: 'root' })
export class ConsentService {
  private key = 'cookie_consent_v1';
  private consentSubject = new BehaviorSubject<ConsentRecord | null>(this.read());
  consent$ = this.consentSubject.asObservable();

  accept(version = '2026-01') {
    const record: ConsentRecord = { state: 'accepted', updatedAt: new Date().toISOString(), version };
    localStorage.setItem(this.key, JSON.stringify(record));
    this.consentSubject.next(record);
  }

  reject(version = '2026-01') {
    const record: ConsentRecord = { state: 'rejected', updatedAt: new Date().toISOString(), version };
    localStorage.setItem(this.key, JSON.stringify(record));
    this.consentSubject.next(record);
  }

  private read(): ConsentRecord | null {
    const raw = localStorage.getItem(this.key);
    return raw ? JSON.parse(raw) : null;
  }
}

Key point: localStorage is client-side only and is not sufficient as legal evidence if you lack server-side logs. Under the regulations, you should send the consent record to your backend to keep an audit trail: user ID, anonymous ID, timestamp, banner version, truncated IP (if your internal policy allows), and the collection source.

Should a guard be used to block tracking cookies?

Yes, but for the right purpose. A guard is not to block users “because they haven’t consented,” but to block routes or features that depend on scripts/cookies that are not yet permitted.

Example: a route /analytics only for admins, but the dashboard pulls data from the Google Analytics API or an SDK according to consent. When consent is missing, the guard redirects to an explanation screen.

@Injectable({ providedIn: 'root' })
export class ConsentGuard implements CanActivate {
  constructor(private consent: ConsentService, private router: Router) {}

  canActivate(): boolean {
    const record = this.consent['consentSubject'].value;
    if (record?.state === 'accepted') return true;
    this.router.navigate(['/cookie-preferences']);
    return false;
  }
}

Practical note: for many sites, you don’t need guards for every route. Only guard functionality that depends on tracking or third parties. More importantly, block scripts from the start.

How do you load scripts dynamically by consent in Angular?

This is the core of “angular cookie consent pdpl”: do not put a script in index.html if it may only run after consent.

A common approach is to use a script loading service:

@Injectable({ providedIn: 'root' })
export class ScriptLoaderService {
  load(src: string, id: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (document.getElementById(id)) return resolve();
      const script = document.createElement('script');
      script.id = id;
      script.src = src;
      script.async = true;
      script.onload = () => resolve();
      script.onerror = () => reject(new Error(`Failed to load ${src}`));
      document.body.appendChild(script);
    });
  }
}

Then only call it after the user has consented:

this.consent.consent$.subscribe(record => {
  if (record?.state === 'accepted') {
    this.scriptLoader.load('https://www.googletagmanager.com/gtag/js?id=G-XXXX', 'gtag-js');
  }
});

If you use Tag Manager, chat widgets, reCAPTCHA, Hotjar, ad pixels… the principle is the same: load after consent, and provide a mechanism to disable again if the user changes their mind.

What is the implementation checklist for an Angular team?

  1. Inventory all scripts and cookies

    review `index.html`, `main.ts`, third-party SDKs, iframes, pixels, chat widgets, A/B testing.

  2. Categorize by purpose

    necessary, analytics, marketing, functionality; default off for non-essential categories.

  3. Design the banner and preference center

    clear accept all, decline all, and per-category choices.

  4. Store evidence of consent

    server-side storage of banner version, timestamp, status, and user/anonymous ID per internal policy.

  5. Only load scripts after consent

    use a loader service, don’t hardcode into HTML.

  6. Allow users to change their mind

    a footer link to reopen settings; when declined, stop loading new scripts.

When do you need a lawyer or a deeper review?

If your app uses remarketing, profiling, foreign SDKs, cross-border data transfers, or synchronizes consent with multiple systems like CRM/CDP/GA4/Meta, review the setup with counsel and your security team. The PDPL is new, and guiding decrees will clarify many technical details and specific penalties.

If you are building a banner, storing evidence of consent, or need to connect consent status with your backend/DSAR, consent.vn can help you design a practical flow for Angular instead of stopping at a popup.

Not every script must be loaded dynamically, but non-essential scripts or those for analytics/marketing should only load after consent, per regulations.
Use both if possible: localStorage for responsive UI, backend for evidence of consent and an audit trail.
Not necessarily. Only guard functionality that depends on consent or third-party scripts.
Yes, but you must ensure only non-essential cookies/scripts are disabled and that you don’t collect beyond the purposes disclosed under the regulations.

Source: the Personal Data Protection Law (Law 91/2025/QH15) and Decree 13/2023/ND-CP on thuvienphapluat.vn; enforcement agency A05 on bocongan.gov.vn

Get started — set up in 5 minutes.

Need help with PDPL compliance?

Get started