@ngrithms/cookie-consent

Modern Angular cookie consent — standalone, signal-first, SSR-safe, zero runtime deps.

npm install @ngrithms/cookie-consent

The banner at the bottom of the page and the floating badge in the corner are running @ngrithms/cookie-consent v0.5 against this site. Try the banner first — then scroll down to see how the library lets you gate embeds, drive Google Consent Mode v2, and inspect state live.

Conditional rendering with *ngrIfConsent

The iframe below only mounts when you grant youtube consent (via the Social Media category). Click Reset below, then Accept all — the video appears in real time. No reload.

YouTube embed blocked

Accept Social Media cookies to load this video.

<ng-container *ngrIfConsent="'youtube'; else blocked">
  <iframe src="https://www.youtube.com/embed/..."></iframe>
</ng-container>
<ng-template #blocked>
  <p>Accept Social Media cookies to load this video.</p>
</ng-template>

Quick controls

Inside the library

Two reactive views into what the library is doing — each paired with the setup it came from, so you can trace the output back to the lines that produced it.

1. Consent state

ConsentService persists user decisions in a single first-party cookie (ngrithms_consent_state). The granted record below is keyed by every CookieItem.key across the categories you declared at setup. Each toggle in the banner flips one entry.

Setup — what this site registers in app.config.ts:

import {
  provideCookieConsent, makeCategory,
  GOOGLE_ANALYTICS, HOTJAR,
  GOOGLE_ADS, META_PIXEL,
  YOUTUBE,
} from '@ngrithms/cookie-consent';

export const appConfig: ApplicationConfig = {
  providers: [
    provideCookieConsent({
      privacyPolicyUrl: '/privacy',
      defaultLanguage: 'en',
      position: 'bottom-bar',
      theme: 'default',
      categories: [
        // Pick the items you've integrated; group them however you want.
        makeCategory({
          key: 'analytics',
          name: { en: 'Analytics' },
          items: [GOOGLE_ANALYTICS, HOTJAR],
        }),
        makeCategory({
          key: 'tracking',
          name: { en: 'Tracking & Ads' },
          items: [GOOGLE_ADS, META_PIXEL],
        }),
        makeCategory({
          key: 'embeds',
          name: { en: 'Third-party embeds' },
          items: [YOUTUBE],
        }),
      ],
    }),
  ],
};

Live state:

null

2. Google Consent Mode v2 payload

The GA adapter bridges consent decisions to Google’s gtag('consent', 'update', ...) API. A mapping translates your CookieItem.key values into Google’s consent signals. Only items for Google’s own products (GA4, Google Ads, GTM) belong here — tools like Hotjar or Meta Pixel have their own consent APIs and stay out of it.

Setup — the mapping used on this page:

import { type GoogleConsentMapping } from '@ngrithms/cookie-consent';

const GA_MAPPING: GoogleConsentMapping = {
  google_analytics: 'analytics_storage',
  google_ads: ['ad_storage', 'ad_user_data', 'ad_personalization'],
};

Two ways to use it: consentToGoogleConsentObject(state, mapping) is a pure transform — that’s what this page calls below for inspection. In production you’d typically use applyGoogleConsentMode instead, which subscribes to consent changes and fires gtag automatically:

import { applyGoogleConsentMode } from '@ngrithms/cookie-consent';

applyGoogleConsentMode(consentService, {
  mapping: GA_MAPPING,
  defaults: {
    analytics_storage: 'denied',
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
  },
});

Live payload:

{
  "analytics_storage": "denied",
  "ad_storage": "denied",
  "ad_user_data": "denied",
  "ad_personalization": "denied"
}

Reactive *ngrIfConsent gates

These flip live as you accept or reject individual cookie items.

google_analyticsdenied
hotjardenied
meta_pixeldenied
youtubedenied

Quick start

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import {
  provideCookieConsent, makeCategory,
  GOOGLE_ANALYTICS, GOOGLE_ADS, YOUTUBE,
} from '@ngrithms/cookie-consent';

export const appConfig: ApplicationConfig = {
  providers: [
    provideCookieConsent({
      privacyPolicyUrl: '/privacy',
      defaultLanguage: 'en',
      categories: [
        makeCategory({
          key: 'analytics',
          name: { en: 'Analytics' },
          items: [GOOGLE_ANALYTICS],
        }),
        makeCategory({
          key: 'tracking',
          name: { en: 'Tracking & Ads' },
          items: [GOOGLE_ADS],
        }),
      ],
      // Prefer the quick-start route? Drop in a preset instead:
      // categories: [ANALYTICS_PRESET, MARKETING_PRESET],
    }),
  ],
};

// src/app/app.component.ts
import { ConsentBannerComponent, ConsentBadgeComponent, IfConsentDirective } from '@ngrithms/cookie-consent';

@Component({
  imports: [ConsentBannerComponent, ConsentBadgeComponent, IfConsentDirective],
  template: `
    <ngr-consent-banner />
    <ngr-consent-badge />

    <div *ngrIfConsent="'google_analytics'">
      <!-- only rendered after consent -->
    </div>
  `,
})
export class AppComponent {}

See the full README for theming, custom categories, headless mode, schema migration, and the ScriptLoaderService for SDK loading.

Learn more