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>
+17 -2
View File
@@ -12,7 +12,7 @@ import WaveBackground from '../components/WaveBackground.astro';
<div data-trail-box class="bg-neutral-900/60 backdrop-blur-md border border-white/10 rounded-3xl p-8 md:p-12 shadow-2xl mb-20 max-w-3xl mx-auto">
<h1 class="text-4xl md:text-5xl font-bold leading-tight mb-2">Privacy Policy</h1>
<p class="text-gray-500 mb-10">Last updated: 27 September 2026</p>
<p class="text-gray-500 mb-10">Last updated: 25 October 2026</p>
<div class="space-y-8 text-gray-300 text-lg leading-relaxed">
@@ -27,7 +27,7 @@ import WaveBackground from '../components/WaveBackground.astro';
<section class="space-y-3">
<h2 class="text-2xl font-bold text-white">This website</h2>
<ul class="list-disc pl-6 space-y-2">
<li>There are no user accounts, no contact forms, no advertising and no analytics or tracking cookies.</li>
<li>There are no user accounts and no contact forms.</li>
<li>If you email me, your address and message are used only to answer you and are not shared with anyone.</li>
<li>Password-protected galleries keep the password only in your open browser tab; it is not stored after you close it.</li>
<li>
@@ -38,6 +38,21 @@ import WaveBackground from '../components/WaveBackground.astro';
</ul>
</section>
<section class="space-y-3">
<h2 class="text-2xl font-bold text-white">Meta Pixel (only with your consent)</h2>
<p>
If you click "Accept" in the cookie box, the site loads the Meta Pixel from Meta Platforms Ireland Ltd.
I use it to see how visitors coming from my Instagram and Facebook use the site.
</p>
<ul class="list-disc pl-6 space-y-2">
<li>It sets cookies (such as <code>_fbp</code>) and sends Meta information like the pages you visit, your IP address and browser details.</li>
<li>Meta may link this to your Facebook or Instagram account and may transfer data outside the EU. See
<a href="https://www.facebook.com/privacy/policy/" target="_blank" rel="noopener noreferrer" class="text-white underline hover:text-gray-300">Meta's privacy policy</a>.</li>
<li>If you click "Decline" or do nothing, the pixel is never loaded.</li>
<li>You can change your choice at any time via "Cookie settings" at the bottom of every page. Your choice is stored in your own browser.</li>
</ul>
</section>
<section class="space-y-3">
<h2 class="text-2xl font-bold text-white">Photo backup app (Google)</h2>
<p>