export default function astroConsent(options = {}) { const siteName = options.siteName ?? "This website"; const policyUrl = options.policyUrl ?? "/privacy"; const consentDays = options.consent?.days ?? 30; const storageKey = options.consent?.storageKey ?? "astro-consent"; const defaultCategories = { essential: true, analytics: false, marketing: false, ...options.categories }; const ttl = consentDays * 24 * 60 * 60 * 1000; return { name: "astro-consent", hooks: { "astro:config:setup": ({ injectScript }) => { /* ───────────────────────────────────── LOAD USER CSS (required) ───────────────────────────────────── */ injectScript("head-inline", ` (() => { const id = "astro-consent-css"; if (document.getElementById(id)) return; const link = document.createElement("link"); link.id = id; link.rel = "stylesheet"; link.href = "/src/cookiebanner.css"; document.head.appendChild(link); })(); `); /* ───────────────────────────────────── Consent runtime (NO CSS) ───────────────────────────────────── */ injectScript("page", ` (() => { const KEY = "${storageKey}"; const TTL = ${ttl}; function now() { return Date.now(); } function read() { try { const raw = localStorage.getItem(KEY); if (!raw) return null; const data = JSON.parse(raw); if (data.expiresAt < now()) { localStorage.removeItem(KEY); return null; } return data; } catch { return null; } } function write(categories) { localStorage.setItem(KEY, JSON.stringify({ updatedAt: now(), expiresAt: now() + TTL, categories })); } window.astroConsent = { get: read, set: write, reset() { localStorage.removeItem(KEY); location.reload(); } }; })(); `); /* ───────────────────────────────────── Banner + modal UI (NO CSS) ───────────────────────────────────── */ injectScript("page", ` (() => { if (window.astroConsent.get()) return; const state = { ...${JSON.stringify(defaultCategories)} }; const banner = document.createElement("div"); banner.id = "astro-consent-banner"; banner.innerHTML = \`
${siteName} uses cookies
Choose how your data is used. Learn more
\`; document.body.appendChild(banner); banner.querySelector(".cb-accept").onclick = () => { window.astroConsent.set({ essential: true, analytics: true, marketing: true }); banner.remove(); }; banner.querySelector(".cb-reject").onclick = () => { window.astroConsent.set({ essential: true }); banner.remove(); }; banner.querySelector(".cb-manage").onclick = openModal; function openModal() { const modal = document.createElement("div"); modal.id = "astro-consent-modal"; modal.innerHTML = \`

Cookie preferences

Essential Always on
Analytics
Marketing
\`; document.body.appendChild(modal); modal.querySelectorAll(".cb-toggle").forEach(toggle => { const key = toggle.getAttribute("data-key"); if (state[key]) toggle.classList.add("active"); toggle.onclick = () => { state[key] = !state[key]; toggle.classList.toggle("active"); }; }); modal.querySelector(".cb-accept").onclick = () => { window.astroConsent.set({ essential: true, ...state }); modal.remove(); banner.remove(); }; modal.onclick = e => { if (e.target === modal) modal.remove(); }; } })(); `); } } }; }