Add cookie_policy_url field to cookie banners

Introduce a required cookie_policy_url alongside the existing
privacy_policy_url (now optional) so banners can link directly to a
dedicated cookie policy — a compliance best practice recommended by
CNIL, ICO, and the EDPB. Existing rows are seeded from their current
privacy_policy_url value.

Both {{cookie_policy_link}} and {{privacy_policy_link}} placeholders
are supported independently in banner description translations.

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-04-24 18:04:05 +04:00
parent 4982cebb9c
commit 598c6b112c
15 changed files with 142 additions and 56 deletions

View File

@@ -50,7 +50,8 @@ export interface BannerConfig {
version: number;
language: string;
default_language: string;
privacy_policy_url: string;
privacy_policy_url?: string;
cookie_policy_url: string;
consent_expiry_days: number;
consent_mode: "OPT_IN" | "OPT_OUT";
show_branding: boolean;

View File

@@ -187,13 +187,21 @@ export class ProboThemedBanner extends HTMLElement {
if (!raw) return;
if (key === "banner_description") {
let link = "";
let privacyLink = "";
if (config.privacy_policy_url) {
const linkText = this.esc(texts.privacy_policy_link_text ?? "Privacy Policy");
link = `<a href="${this.esc(config.privacy_policy_url)}" target="_blank" rel="noopener noreferrer">${linkText}</a>`;
privacyLink = `<a href="${this.esc(config.privacy_policy_url)}" target="_blank" rel="noopener noreferrer">${linkText}</a>`;
}
const parts = raw.split("{{privacy_policy_link}}");
el.innerHTML = parts.map(p => this.esc(p)).join(link);
let cookieLink = "";
if (config.cookie_policy_url) {
const linkText = this.esc(texts.cookie_policy_link_text ?? "Cookie Policy");
cookieLink = `<a href="${this.esc(config.cookie_policy_url)}" target="_blank" rel="noopener noreferrer">${linkText}</a>`;
}
const segments = raw.split("{{cookie_policy_link}}");
const html = segments.map(seg =>
seg.split("{{privacy_policy_link}}").map(p => this.esc(p)).join(privacyLink),
).join(cookieLink);
el.innerHTML = html;
} else if (key === "panel_description") {
el.textContent = interpolate(raw, { necessary_category: necessaryCategoryName });
} else {