feat(tracking): Meta Pixel behind cookie consent

- Meta Pixel (2453598878495749) loads only after the visitor clicks Accept;
  choice stored in localStorage (ibo-consent).
- Decline after a previous Accept clears _fbp/_fbc and reloads.
- "Cookie settings" link in the footer reopens the banner.
- Privacy page: removed "no tracking cookies", added Meta Pixel section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Linus Olofsson
2026-10-25 18:11:36 +01:00
co-authored by Claude Opus 5.5
parent 3f02b323a3
commit 31d4e540ce
2 changed files with 83 additions and 3 deletions
+66 -1
View File
@@ -39,8 +39,73 @@ const { title } = Astro.props;
&amp;
<a href="https://karleksguiden.se/" target="_blank" rel="noopener noreferrer" data-glow-link="magenta" class="text-gray-400 hover:text-white transition-colors">karleksguiden.se</a>
</p>
<p>&copy; {new Date().getFullYear()} Images by Olofsson. All rights reserved. &middot; <a href="/privacy" class="text-gray-400 hover:text-white transition-colors">Privacy</a></p>
<p>&copy; {new Date().getFullYear()} Images by Olofsson. All rights reserved. &middot; <a href="/privacy" class="text-gray-400 hover:text-white transition-colors">Privacy</a> &middot; <button type="button" data-consent-open class="text-gray-400 hover:text-white transition-colors">Cookie settings</button></p>
</footer>
<!-- Cookie consent: Meta Pixel laddas forst efter "Accept" -->
<div data-consent-banner hidden class="fixed bottom-4 inset-x-4 md:left-auto md:right-6 md:max-w-md z-[60] bg-neutral-900/95 backdrop-blur-md border border-white/10 rounded-2xl p-5 shadow-2xl text-sm text-gray-300">
<p class="mb-4">
I use the Meta Pixel to see how visitors from Instagram and Facebook use this site. It sets cookies and sends data to Meta.
<a href="/privacy" class="text-white underline hover:text-gray-300">Read more</a>
</p>
<div class="flex gap-3 justify-end">
<button type="button" data-consent="denied" class="px-4 py-2 rounded-full border border-white/20 text-gray-300 hover:text-white hover:border-white/40 transition-colors">Decline</button>
<button type="button" data-consent="granted" class="px-4 py-2 rounded-full bg-white text-neutral-900 font-medium hover:bg-gray-200 transition-colors">Accept</button>
</div>
</div>
<script is:inline>
(function () {
var KEY = 'ibo-consent';
var banner = document.querySelector('[data-consent-banner]');
function read() { try { return localStorage.getItem(KEY); } catch (e) { return null; } }
function save(v) { try { localStorage.setItem(KEY, v); } catch (e) {} }
function loadPixel() {
if (window.fbq) return;
/* Meta Pixel Code */
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '2453598878495749');
fbq('track', 'PageView');
/* End Meta Pixel Code */
}
// Aterkallat samtycke: ta bort Metas forsta-parts-cookies.
function clearMetaCookies() {
['_fbp', '_fbc'].forEach(function (name) {
document.cookie = name + '=; Max-Age=0; path=/';
document.cookie = name + '=; Max-Age=0; path=/; domain=.' + location.hostname.replace(/^www\./, '');
});
}
var choice = read();
if (choice === 'granted') loadPixel();
else if (choice !== 'denied') banner.hidden = false;
document.querySelectorAll('[data-consent]').forEach(function (btn) {
btn.addEventListener('click', function () {
var v = btn.getAttribute('data-consent');
var had = read() === 'granted';
save(v);
banner.hidden = true;
if (v === 'granted') loadPixel();
else if (had) { clearMetaCookies(); location.reload(); }
});
});
document.querySelectorAll('[data-consent-open]').forEach(function (btn) {
btn.addEventListener('click', function () { banner.hidden = false; });
});
})();
</script>
</body>
</html>