@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:
null2. 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_analyticsdeniedhotjardeniedmeta_pixeldeniedyoutubedeniedQuick 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.