1<!DOCTYPE html><html lang="en"><head>
1<script> 2 window.dataLayer = window.dataLayer || []; 3 function gtag(){dataLayer.push(arguments);} 4 gtag('consent', 'default', { 5 'ad_storage': 'denied', 6 'ad_user_data': 'denied', 7 'ad_personalization': 'denied', 8 'analytics_storage': 'denied' 9 }); 10 </script>
10<script>
vendor: 368 bytes, lines 10-15
10 11 (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 12 new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 13 j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 14 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 15 })(window,document,'script','dataLayer','
15GTM-MHBLQSM9
vendor: 10 bytes, lines 15-16
15'); 16
16</script>
16<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="Product launches, company milestones, partnerships, and press releases from SnapGlyph."><title>Newsroom - SnapGlyph</title><link rel="canonical" href="https://snapglyph.com/news/"><!-- Hreflang tags for international targeting --><link rel="alternate" hreflang="en-US" href="https://snapglyph.com/news/"><link rel="alternate" hreflang="en-CA" href="https://snapglyph.com/news/"><link rel="alternate" hreflang="en-GB" href="https://snapglyph.com/news/"><link rel="alternate" hreflang="x-default" href="https://snapglyph.com/news/"><!-- Open Graph meta tags --><meta property="og:title" content="Newsroom - SnapGlyph"><meta property="og:description" content="Product launches, company milestones, partnerships, and press releases from SnapGlyph."><meta property="og:url" content="https://snapglyph.com/news/"><meta property="og:site_name" content="SnapGlyph"><meta property="og:type" content="website"><meta property="og:locale" content="en_US"><!-- Twitter Card meta tags --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@snapglyph"><meta name="twitter:title" content="Newsroom - SnapGlyph"><meta name="twitter:description" content="Product launches, company milestones, partnerships, and press releases from SnapGlyph."><link rel="alternate" type="application/rss+xml" title="SnapGlyph Newsroom" href="/news/rss.xml"><link rel="stylesheet" href="/styles.css"><!-- Favicons --><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="icon" href="/favicon.svg" type="image/svg+xml"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@600;700;800&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"><!-- Structured Data -->
16<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"SnapGlyph","url":"https://snapglyph.com","logo":"https://snapglyph.com/logo.png","description":"QR codes, branded short links, and link-in-bio pages. One platform for every link you share.","sameAs":["https://twitter.com/snapglyph","https://linkedin.com/company/snapglyph"]}</script>
16<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"SnapGlyph","url":"https://snapglyph.com","description":"QR Codes, Short Links & Link-in-Bio â Link Management Platform"}</script>
16<script type="application/ld+json">{"@context":"https://schema.org","@type":"CollectionPage","name":"SnapGlyph Newsroom","description":"Product launches, company milestones, partnerships, and press releases from SnapGlyph.","url":"https://snapglyph.com/news","mainEntity":{"@type":"ItemList","itemListElement":[{"@type":"ListItem","position":1,"url":"https://snapglyph.com/news/snapglyph-launches-on-product-hunt","name":"SnapGlyph Launches on Product Hunt"},{"@type":"ListItem","position":2,"url":"https://snapglyph.com/news/snapglyph-releases-mcp-server","name":"SnapGlyph Releases SnapGlyph MCP Server"},{"@type":"ListItem","position":3,"url":"https://snapglyph.com/news/snapglyph-introduces-parameter-management","name":"SnapGlyph Introduces Link Tracking Parameter Management"},{"@type":"ListItem","position":4,"url":"https://snapglyph.com/news/snapglyph-releases-smart-qr-codes-and-smart-shortlinks","name":"SnapGlyph Releases Smart QR Codes and Smart Shortlinks"}]}}</script>
16<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://snapglyph.com"},{"@type":"ListItem","position":2,"name":"Newsroom","item":"https://snapglyph.com/news"}]}</script>
16</head><body>
vendor: 67 bytes, line 16
16<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
16GTM-MHBLQSM9
vendor: 82 bytes, line 16
16" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
16<nav class="nav"><div class="nav-container"><a href="/" class="nav-logo"><img src="/_astro/logo.C49gomSg_gExLD.svg" alt="SnapGlyph" loading="lazy" decoding="async" width="100" height="10"></a><div class="nav-links"><div class="nav-dropdown"><button class="nav-dropdown-toggle" aria-expanded="false" aria-haspopup="true">Features<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 5l3 3 3-3"></path></svg></button><div class="nav-dropdown-menu"><a href="/features/qr-codes/">QR Code Generator</a><a href="/features/url-shortener/">Link Shortener</a><a href="/features/link-in-bio/">Link in Bio</a><a href="/features/snapglyph-mcp/">SnapGlyph MCP</a></div></div><a href="/pricing/">Pricing</a><div class="nav-dropdown nav-resources-dropdown"><button class="nav-dropdown-toggle" aria-expanded="false" aria-haspopup="true">Resources<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 5l3 3 3-3"></path></svg></button><div class="nav-dropdown-menu nav-mega-menu"><div class="nav-mega-col"><span class="nav-mega-heading">Use Cases</span><a href="/use-cases/business-owners/"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="12" height="10" rx="1.5"></rect><line x1="5" y1="6" x2="8" y2="6"></line><line x1="5" y1="8.5" x2="7" y2="8.5"></line><rect x="9.5" y="6" width="3" height="3" rx="0.5"></rect></svg>For Business</a><a href="/use-cases/restaurants/"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 2v5a2 2 0 002 2h0a2 2 0 002-2V2"></path><line x1="6" y1="9" x2="6" y2="14"></line><line x1="12" y1="2" x2="12" y2="6"></line><path d="M10 2v3a2 2 0 002 2h0V14"></path></svg>For Restaurants</a></div><div class="nav-mega-divider"></div><div class="nav-mega-col"><span class="nav-mega-heading">Learn</span><a href="/blog/"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 2.5h7a2 2 0 012 2V13a0.5 0.5 0 01-0.5 0.5H5a2 2 0 01-2-2V2.5z"></path><line x1="5.5" y1="5.5" x2="9.5" y2="5.5"></line><line x1="5.5" y1="8" x2="9.5" y2="8"></line><line x1="5.5" y1="10.5" x2="8" y2="10.5"></line></svg>Blog</a><a href="/compare/"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="8" y1="3" x2="8" y2="13.5"></line><line x1="6" y1="13.5" x2="10" y2="13.5"></line><line x1="2.5" y1="5" x2="13.5" y2="5"></line><line x1="3.5" y1="5" x2="3.5" y2="8"></line><line x1="12.5" y1="5" x2="12.5" y2="8"></line><path d="M1.5 8 Q3.5 11 5.5 8"></path><path d="M10.5 8 Q12.5 11 14.5 8"></path></svg>Comparisons</a></div><div class="nav-mega-divider"></div><div class="nav-mega-col nav-mega-blog"><span class="nav-mega-heading">Latest from SnapGlyph</span><a href="/blog/practical-guide-to-using-qr-codes/" class="nav-mega-post"><img src="/_astro/practical-guide-cover.6-cUzm15_127Ebd.webp" alt loading="lazy" decoding="async" width="2064" height="512" class="nav-mega-post-img"><span class="nav-mega-post-title">A Practical Guide to Using QR Codes</span></a><a href="/blog/" class="nav-mega-blog-link">View all articles →</a></div></div></div></div><div class="nav-auth"><a href="/support/" target="_blank" class="nav-support-link">Support</a><a href="https://app.snapglyph.com/auth/signin" class="nav-btn-secondary" data-track="signin_click" data-track-location="nav">Sign In</a><a href="https://app.snapglyph.com/auth/signup" class="nav-cta" data-track="cta_click" data-track-location="nav" data-track-text="Get Started">Get Started</a></div><button class="nav-mobile-toggle" aria-label="Toggle menu" aria-expanded="false"><svg class="nav-icon-menu" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg><svg class="nav-icon-close" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div><div class="nav-mobile-menu"><div class="nav-mobile-links"><div class="nav-mobile-dropdown"><button class="nav-mobile-dropdown-toggle" aria-expanded="false">Features<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 5l3 3 3-3"></path></svg></button><div class="nav-mobile-dropdown-menu"><a href="/features/qr-codes/">QR Code Generator</a><a href="/features/url-shortener/">Link Shortener</a><a href="/features/link-in-bio/">Link in Bio</a><a href="/features/snapglyph-mcp/">SnapGlyph MCP</a></div></div><a href="/pricing/">Pricing</a><div class="nav-mobile-dropdown nav-mobile-resources-dropdown"><button class="nav-mobile-dropdown-toggle" aria-expanded="false">Resources<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 5l3 3 3-3"></path></svg></button><div class="nav-mobile-dropdown-menu"><span class="nav-mobile-dropdown-heading">Use Cases</span><a href="/use-cases/business-owners/">For Business</a><a href="/use-cases/restaurants/">For Restaurants</a><span class="nav-mobile-dropdown-heading nav-mobile-dropdown-heading-spaced">Compare</span><a href="/compare/snapglyph-vs-linktree/">vs. Linktree</a><a href="/compare/snapglyph-vs-bitly/">vs. Bitly</a><a href="/compare/snapglyph-vs-beaconstac/">vs. Beaconstac</a><a href="/compare/snapglyph-vs-rebrandly/">vs. Rebrandly</a><a href="/compare/snapglyph-vs-beacons/">vs. Beacons</a><span class="nav-mobile-dropdown-heading nav-mobile-dropdown-heading-spaced">Blog</span><a href="/blog/">View all articles</a><span class="nav-mobile-dropdown-heading nav-mobile-dropdown-heading-spaced">
16Newsroom</span><a href="/news/">Latest news</a></div></div></div><div class="nav-mobile-auth"><a href="/support/" target="_blank" class="nav-support-link">Support</a><a href="https://app.snapglyph.com/auth/signin" class="nav-btn-secondary" data-track="signin_click" data-track-location="mobile_nav">Sign In</a><a href="https://app.snapglyph.com/auth/signup" class="nav-cta" data-track="cta_click" data-track-location="mobile_nav" data-track-text="Get Started">Get Started</a></div></div></nav><main class="newsroom-page"><div class="newsroom-container"><header class="newsroom-header"><span class="newsroom-eyebrow">Newsroom</span><h1>Latest from SnapGlyph</h1><p>Product launches, company milestones, and press from the team building SnapGlyph.</p><a href="/news/rss.xml" class="newsroom-rss-link" aria-label="Subscribe to the SnapGlyph newsroom RSS feed"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle></svg>Subscribe via RSS</a></header><a class="newsroom-featured" href="https://www.producthunt.com/posts/snapglyph" data-category="product" target="_blank" rel="noopener noreferrer"><div class="newsroom-featured-media"><img src="/_astro/snapglyph-launches-on-product-hunt.DMeHxwyV_ZxzgdE.webp" alt="SnapGlyph Launches on Product Hunt - Image generated using AI." loading="eager" decoding="async" width="1200" height="675"></div><div class="newsroom-featured-body"><div class="newsroom-featured-meta"><span class="newsroom-tag" data-category="product">Product</span><span class="newsroom-dateline">CALGARY, AB</span><time datetime="2026-08-02T00:00:00.000Z">August 2, 2026</time></div><h2>SnapGlyph Launches on Product Hunt</h2><p>QR codes, branded short links, and Link Hubs in one tool â SnapGlyph is now live on Product Hunt.</p><span class="newsroom-featured-cta">Read on Product Hunt<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="13 6 19 12 13 18"></polyline></svg></span></div></a><div class="newsroom-secondary-grid"><a class="newsroom-card newsroom-card-compact" href="/news/snapglyph-releases-mcp-server/" data-category="product"><div class="newsroom-card-image"><img src="/_astro/snapglyph-releases-mcp-server.De4lpra8_ZzmRhx.webp" alt="SnapGlyph Releases SnapGlyph MCP Server - Image generated using AI." loading="lazy" decoding="async" width="1200" height="676"></div><div class="newsroom-card-body"><div class="newsroom-card-meta"><span class="newsroom-tag" data-category="product">Product</span><time datetime="2026-06-29T00:00:00.000Z">June 29, 2026</time></div><h3>SnapGlyph Releases SnapGlyph MCP Server</h3><p>QR code and tracked shortlink generation now happens inside the AI tools organizations and business operators already use â no app-switching required.</p></div></a><a class="newsroom-card newsroom-card-compact" href="/news/snapglyph-introduces-parameter-management/" data-category="product"><div class="newsroom-card-image"><img src="/_astro/snapglyph-introduces-parameter-management.DG4x9YBp_2oKvJe.webp" alt="SnapGlyph Introduces Link Tracking Parameter Management - Image generated using AI." loading="lazy" decoding="async" width="1200" height="676"></div><div class="newsroom-card-body"><div class="newsroom-card-meta"><span class="newsroom-tag" data-category="product">Product</span><time datetime="2026-06-19T00:00:00.000Z">June 19, 2026</time></div><h3>SnapGlyph Introduces Link Tracking Parameter Management</h3><p>New controls and governance for UTM tracking parameters keep tracking data consistent across teams â and make pre-set parameters one click to apply.</p></div></a></div><div class="newsroom-archive" data-active-category="all"><div class="newsroom-filters" role="tablist" aria-label="Filter news by category"><button type="button" class="newsroom-chip is-active" data-filter="all" role="tab" aria-selected="true">All</button><button type="button" class="newsroom-chip" data-filter="product" role="tab" aria-selected="false">Product</button><button type="button" class="newsroom-chip" data-filter="company" role="tab" aria-selected="false">Company</button><button type="button" class="newsroom-chip" data-filter="press-release" role="tab" aria-selected="false">Press</button><button type="button" class="newsroom-chip" data-filter="partnerships" role="tab" aria-selected="false">Partnerships</button><button type="button" class="newsroom-chip" data-filter="events" role="tab" aria-selected="false">Events</button><button type="button" class="newsroom-chip" data-filter="awards" role="tab" aria-selected="false">Awards</button></div><section class="newsroom-year-section"><div class="newsroom-year-divider"><span>2026</span><span class="newsroom-year-rule" aria-hidden="true"></span></div>
16<div class="newsroom-grid"><a class="newsroom-card" href="/news/snapglyph-releases-smart-qr-codes-and-smart-shortlinks/" data-category="product"><div class="newsroom-card-image"><img src="/_astro/snapglyph-releases-smart-qr-codes-and-smart-shortlinks.BR1b6zAf_Z2hhUo2.webp" alt="SnapGlyph Releases Smart QR Codes and Smart Shortlinks - Image generated using AI." loading="lazy" decoding="async" width="1200" height="676"></div><div class="newsroom-card-body"><div class="newsroom-card-meta"><span class="newsroom-tag" data-category="product">Product</span><time datetime="2026-05-09T00:00:00.000Z">May 9, 2026</time></div><h3>SnapGlyph Releases Smart QR Codes and Smart Shortlinks</h3><p>A single QR code or short link can now route to different destinations based on the day of the week or time of day, automatically.</p></div></a></div></section></div></div></main>
16<script> 17 (function () { 18 const archive = document.querySelector('.newsroom-archive'); 19 if (!archive) return; 20 const chips = archive.querySelectorAll('.newsroom-chip'); 21 chips.forEach((chip) => { 22 chip.addEventListener('click', () => { 23 const value = chip.getAttribute('data-filter') || 'all'; 24 archive.setAttribute('data-active-category', value); 25 chips.forEach((c) => { 26 const active = c === chip; 27 c.classList.toggle('is-active', active); 28 c.setAttribute('aria-selected', active ? 'true' : 'false'); 29 }); 30 }); 31 }); 32 })(); 33 </script>
33<footer class="footer"><div class="footer-container"><div class="footer-brand"><a href="/" class="footer-logo"><img src="/_astro/logo-light.BnTDjf0p_gExLD.svg" alt="SnapGlyph" loading="lazy" decoding="async" width="100" height="10"></a><p>QR codes, shortlinks, and link-in-bio pages.</p><address class="footer-address"><strong>SnapGlyph Software</strong><br>#1009 - 3909 University Ave NW<br>Calgary, AB, Canada T3B 6K3</address><div class="footer-social"><a href="https://www.linkedin.com/company/snapglyph" target="_blank" rel="noopener noreferrer" aria-label="SnapGlyph on LinkedIn" data-track="social_click" data-track-network="linkedin" data-track-location="footer"><svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.34V9h3.42v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28zM5.34 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13zM7.12 20.45H3.55V9h3.57v11.45zM22.22 0H1.77C.79 0 0 .77 0 1.73v20.54C0 23.22.79 24 1.77 24h20.45c.98 0 1.78-.78 1.78-1.73V1.73C24 .77 23.2 0 22.22 0z"></path></svg></a></div></div><div class="footer-links"><div class="footer-column"><h4>Product</h4><a href="/features/qr-codes/">QR Codes</a><a href="/features/url-shortener/">Link Shortener</a><a href="/features/link-in-bio/">Link in Bio</a><a href="/pricing/">Pricing</a><a href="/features/snapglyph-mcp/">SnapGlyph MCP</a></div><div class="footer-column"><h4>Company</h4><a href="/about/">About</a><a href="/contact/">Contact</a><a href="/news/">Newsroom</a><a href="/ai-instructions/">AI Instructions</a></div><div class="footer-column"><h4>Use Cases</h4><a href="/use-cases/business-owners/">For Business</a><a href="/use-cases/restaurants/">For Restaurants</a></div><div class="footer-column"><h4>Compare</h4><a href="/compare/">All Comparisons</a><a href="/compare/snapglyph-vs-linktree/">vs. Linktree</a><a href="/compare/snapglyph-vs-bitly/">vs. Bitly</a><a href="/compare/snapglyph-vs-beaconstac/">vs. Beaconstac</a><a href="/compare/snapglyph-vs-rebrandly/">vs. Rebrandly</a><a href="/compare/snapglyph-vs-beacons/">vs. Beacons</a></div><div class="footer-column"><h4>Resources</h4><a href="/support/" target="_blank">Support</a><a href="/blog/">Blog</a><a href="/faq/">FAQ</a><a href="https://app.snapglyph.com/docs/api" target="_blank" rel="noopener noreferrer">API Docs</a></div></div></div><div class="footer-bottom"><div class="footer-legal-links"><a href="/privacy/">Privacy Policy</a><a href="/terms/">Terms of Service</a><a href="/cookies/">Cookie Policy</a><a href="/subprocessors/">Subprocessors</a><button type="button" class="footer-cookie-btn" id="open-cookie-settings">Cookie Options</button><a href="https://status.snapglyph.com" target="_blank" rel="noopener noreferrer">Status</a></div><p>© 2026 SnapGlyph Software. All rights reserved.</p></div></footer>
33<script> 34 // Mobile nav toggle 35 const mobileToggle = document.querySelector('.nav-mobile-toggle'); 36 const mobileMenu = document.querySelector('.nav-mobile-menu'); 37 const nav = document.querySelector('.nav'); 38 39 if (nav) { 40 mobileToggle?.addEventListener('click', function() { 41 const isOpen = nav.classList.toggle('nav-open'); 42 mobileToggle.setAttribute('aria-expanded', isOpen); 43 }); 44 45 // Close menu when clicking a link (but not dropdown toggles) 46 document.querySelectorAll('.nav-mobile-menu a').forEach(link => { 47 link.addEventListener('click', () => { 48 nav.classList.remove('nav-open'); 49 mobileToggle?.setAttribute('aria-expanded', 'false'); 50 }); 51 }); 52 53 // Close menu when clicking outside 54 document.addEventListener('click', (e) => { 55 if (nav.classList.contains('nav-open') && !nav.contains(e.target)) { 56 nav.classList.remove('nav-open'); 57 mobileToggle?.setAttribute('aria-expanded', 'false'); 58 } 59 }); 60 61 // Desktop dropdown toggles (supports multiple) 62 document.querySelectorAll('.nav-dropdown').forEach(dropdown => { 63 const toggle = dropdown.querySelector('.nav-dropdown-toggle'); 64 toggle?.addEventListener('click', function(e) { 65 e.preventDefault(); 66 // Close other open dropdowns 67 document.querySelectorAll('.nav-dropdown').forEach(other => { 68 if (other !== dropdown) { 69 other.classList.remove('nav-dropdown-open'); 70 other.querySelector('.nav-dropdown-toggle')?.setAttribute('aria-expanded', 'false'); 71 } 72 }); 73 const isOpen = dropdown.classList.toggle('nav-dropdown-open'); 74 toggle.setAttribute('aria-expanded', isOpen); 75 }); 76 }); 77 78 // Close desktop dropdowns when clicking outside 79 document.addEventListener('click', (e) => { 80 document.querySelectorAll('.nav-dropdown').forEach(dropdown => { 81 if (!dropdown.contains(e.target)) { 82 dropdown.classList.remove('nav-dropdown-open'); 83 dropdown.querySelector('.nav-dropdown-toggle')?.setAttribute('aria-expanded', 'false'); 84 } 85 }); 86 }); 87 88 // Mobile dropdown toggles (supports multiple) 89 document.querySelectorAll('.nav-mobile-dropdown').forEach(dropdown => { 90 const toggle = dropdown.querySelector('.nav-mobile-dropdown-toggle'); 91 toggle?.addEventListener('click', function(e) { 92 e.preventDefault(); 93 const isOpen = dropdown.classList.toggle('nav-mobile-dropdown-open'); 94 toggle.setAttribute('aria-expanded', isOpen); 95 }); 96 }); 97 } 98 </script>
98<!-- Cookie Consent Banner --><div id="cookie-consent-banner" class="cookie-banner" style="display: none;"><div class="cookie-banner-content"><!-- Step 1: Initial View --><div id="cookie-step-1" class="cookie-step"><div class="cookie-banner-text"><h3>How we use Cookies</h3><p>We use cookies to enhance your experience and analyze site traffic.</p></div><div class="cookie-banner-actions"><button type="button" class="cookie-btn cookie-btn-secondary" id="cookie-customize">Customize</button><button type="button" class="cookie-btn cookie-btn-primary" id="cookie-accept-all">Accept All</button></div></div><!-- Step 2: Customize View --><div id="cookie-step-2" class="cookie-step" style="display: none;"><div class="cookie-banner-header"><button type="button" class="cookie-back-btn" id="cookie-back" aria-label="Go back"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 12L6 8L10 4"></path></svg></button><h3>Customize Cookies</h3></div><div class="cookie-options"><div class="cookie-option"><div class="cookie-option-left"><span class="cookie-option-label">Required</span><button type="button" class="cookie-info-btn" data-tooltip="Essential for the website to function properly" aria-label="More info"><svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8 8 0 100 16A8 8 0 008 0zm0 14.5a6.5 6.5 0 110-13 6.5 6.5 0 010 13zM8 6a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 018 6zm0-2.5a1 1 0 100 2 1 1 0 000-2z"></path></svg></button></div><div class="cookie-toggle cookie-toggle-required"><input type="checkbox" id="cookie-required" checked disabled><label for="cookie-required"></label></div></div><div class="cookie-option"><div class="cookie-option-left"><span class="cookie-option-label">Analytics</span><button type="button" class="cookie-info-btn" data-tooltip="Help us understand how visitors interact with our website" aria-label="More info"><svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8 8 0 100 16A8 8 0 008 0zm0 14.5a6.5 6.5 0 110-13 6.5 6.5 0 010 13zM8 6a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 018 6zm0-2.5a1 1 0 100 2 1 1 0 000-2z"></path></svg></button></div><div class="cookie-toggle"><input type="checkbox" id="cookie-analytics"><label for="cookie-analytics"></label></div></div><div class="cookie-option"><div class="cookie-option-left"><span class="cookie-option-label">Marketing</span><button type="button" class="cookie-info-btn" data-tooltip="Used to deliver relevant ads and track campaign performance" aria-label="More info"><svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8 8 0 100 16A8 8 0 008 0zm0 14.5a6.5 6.5 0 110-13 6.5 6.5 0 010 13zM8 6a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 018 6zm0-2.5a1 1 0 100 2 1 1 0 000-2z"></path></svg></button></div><div class="cookie-toggle"><input type="checkbox" id="cookie-marketing"><label for="cookie-marketing"></label></div></div><div class="cookie-option"><div class="cookie-option-left"><span class="cookie-option-label">Advertising</span><button type="button" class="cookie-info-btn" data-tooltip="Enable personalized advertising across platforms" aria-label="More info"><svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8 8 0 100 16A8 8 0 008 0zm0 14.5a6.5 6.5 0 110-13 6.5 6.5 0 010 13zM8 6a.75.75 0 01.75.75v4.5a.75.75 0 01-1.5 0v-4.5A.75.75 0 018 6zm0-2.5a1 1 0 100 2 1 1 0 000-2z"></path></svg></button></div><div class="cookie-toggle"><input type="checkbox" id="cookie-advertising"><label for="cookie-advertising"></label></div></div></div><div class="cookie-banner-actions"><button type="button" class="cookie-btn cookie-btn-secondary" id="cookie-reject-all">Reject All</button><button type="button" class="cookie-btn cookie-btn-primary" id="cookie-save-choices">Save Choices</button></div></div></div></div>
98<script> 99 (function() { 100 const COOKIE_NAME = 'snapglyph_cookie_consent'; 101 const COOKIE_EXPIRY_DAYS = 365; 102 103 // Get cookie value 104 function getCookie(name) { 105 const value = `; ${document.cookie}`; 106 const parts = value.split(`; ${name}=`); 107 if (parts.length === 2) return parts.pop().split(';').shift(); 108 return null; 109 } 110 111 // Set cookie with expiry 112 function setCookie(name, value, days) { 113 const date = new Date(); 114 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 115 const expires = `expires=${date.toUTCString()}`; 116 document.cookie = `${name}=${value};${expires};path=/;SameSite=Lax`; 117 } 118 119 // Push consent to GTM dataLayer and update Google Consent Mode v2 120 function pushConsentToGTM(consent) { 121 window.dataLayer = window.dataLayer || []; 122 123 // Google Consent Mode v2 update 124 function gtag(){dataLayer.push(arguments);} 125 gtag('consent', 'update', { 126 'analytics_storage': consent.analytics ? 'granted' : 'denied', 127 'ad_storage': consent.advertising ? 'granted' : 'denied', 128 'ad_user_data': consent.marketing ? 'granted' : 'denied', 129 'ad_personalization': consent.advertising ? 'granted' : 'denied' 130 }); 131 132 // Custom dataLayer events for GTM triggers 133 window.dataLayer.push({ 134 'event': 'cookie_consent_update', 135 'cookie_consent_analytics': consent.analytics, 136 'cookie_consent_marketing': consent.marketing, 137 'cookie_consent_advertising': consent.advertising 138 }); 139 140 if (consent.analytics) { 141 window.dataLayer.push({ 'event': 'consent_analytics' }); 142 } 143 if (consent.marketing) { 144 window.dataLayer.push({ 'event': 'consent_marketing' }); 145 } 146 if (consent.advertising) { 147 window.dataLayer.push({ 'event': 'consent_advertising' }); 148 } 149 } 150 151 // Save preferences 152 function savePreferences(analytics, marketing, advertising) { 153 const consent = { 154 required: true, 155 analytics: analytics, 156 marketing: marketing, 157 advertising: advertising, 158 timestamp: new Date().toISOString() 159 }; 160 setCookie(COOKIE_NAME, JSON.stringify(consent), COOKIE_EXPIRY_DAYS); 161 pushConsentToGTM(consent); 162 hideBanner(); 163 } 164 165 // Show banner 166 function showBanner(showCustomize) { 167 const banner = document.getElementById('cookie-consent-banner'); 168 const step1 = document.getElementById('cookie-step-1'); 169 const step2 = document.getElementById('cookie-step-2'); 170 171 if (banner) { 172 // Show appropriate step 173 if (showCustomize) { 174 step1.style.display = 'none'; 175 step2.style.display = 'block'; 176 } else { 177 step1.style.display = 'block'; 178 step2.style.display = 'none'; 179 } 180 banner.style.display = 'flex'; 181 setTimeout(() => banner.classList.add('cookie-banner-visible'), 10); 182 } 183 } 184 185 // Hide banner 186 function hideBanner() { 187 const banner = document.getElementById('cookie-consent-banner'); 188 if (banner) { 189 banner.classList.remove('cookie-banner-visible'); 190 setTimeout(() => { 191 banner.style.display = 'none'; 192 // Reset to step 1 193 document.getElementById('cookie-step-1').style.display = 'block'; 194 document.getElementById('cookie-step-2').style.display = 'none'; 195 }, 300); 196 } 197 } 198 199 // Switch to customize view 200 function showCustomizeStep() { 201 const step1 = document.getElementById('cookie-step-1'); 202 const step2 = document.getElementById('cookie-step-2'); 203 step1.style.display = 'none'; 204 step2.style.display = 'block'; 205 } 206 207 // Switch back to initial view 208 function showInitialStep() { 209 const step1 = document.getElementById('cookie-step-1'); 210 const step2 = document.getElementById('cookie-step-2'); 211 step1.style.display = 'block'; 212 step2.style.display = 'none'; 213 } 214 215 // Load saved preferences into checkboxes 216 function loadPreferencesIntoUI(consent) { 217 document.getElementById('cookie-analytics').checked = consent.analytics; 218 document.getElementById('cookie-marketing').checked = consent.marketing; 219 document.getElementById('cookie-advertising').checked = consent.advertising; 220 } 221 222 // Initialize on DOM ready
223 function init() { 224 const acceptAllBtn = document.getElementById('cookie-accept-all'); 225 const rejectAllBtn = document.getElementById('cookie-reject-all'); 226 const customizeBtn = document.getElementById('cookie-customize'); 227 const backBtn = document.getElementById('cookie-back'); 228 const saveChoicesBtn = document.getElementById('cookie-save-choices'); 229 const openSettingsBtn = document.getElementById('open-cookie-settings'); 230 231 // Check for existing consent 232 const existingConsent = getCookie(COOKIE_NAME); 233 234 if (existingConsent) { 235 try { 236 const consent = JSON.parse(existingConsent); 237 loadPreferencesIntoUI(consent); 238 pushConsentToGTM(consent); 239 } catch (e) { 240 showBanner(false); 241 } 242 } else { 243 showBanner(false); 244 } 245 246 // Accept all 247 acceptAllBtn?.addEventListener('click', function() { 248 savePreferences(true, true, true); 249 }); 250 251 // Customize button - go to step 2 252 customizeBtn?.addEventListener('click', function() { 253 showCustomizeStep(); 254 }); 255 256 // Back button - go to step 1 257 backBtn?.addEventListener('click', function() { 258 showInitialStep(); 259 }); 260 261 // Reject all (only required cookies) 262 rejectAllBtn?.addEventListener('click', function() { 263 savePreferences(false, false, false); 264 }); 265 266 // Save current choices 267 saveChoicesBtn?.addEventListener('click', function() { 268 const analytics = document.getElementById('cookie-analytics').checked; 269 const marketing = document.getElementById('cookie-marketing').checked; 270 const advertising = document.getElementById('cookie-advertising').checked; 271 savePreferences(analytics, marketing, advertising); 272 }); 273 274 // Open cookie settings from footer - go directly to customize 275 openSettingsBtn?.addEventListener('click', function() { 276 const existingConsent = getCookie(COOKIE_NAME); 277 if (existingConsent) { 278 try { 279 const consent = JSON.parse(existingConsent); 280 loadPreferencesIntoUI(consent); 281 } catch (e) {} 282 } 283 showBanner(true); 284 }); 285 286 // Tooltip functionality for info buttons 287 document.querySelectorAll('.cookie-info-btn').forEach(function(btn) { 288 // For touch devices 289 btn.addEventListener('click', function(e) { 290 e.preventDefault(); 291 const allTooltips = document.querySelectorAll('.cookie-info-btn'); 292 allTooltips.forEach(function(t) { 293 if (t !== btn) t.classList.remove('tooltip-active'); 294 }); 295 btn.classList.toggle('tooltip-active'); 296 }); 297 }); 298 299 // Close tooltips when clicking outside 300 document.addEventListener('click', function(e) { 301 if (!e.target.closest('.cookie-info-btn')) { 302 document.querySelectorAll('.cookie-info-btn').forEach(function(btn) { 303 btn.classList.remove('tooltip-active'); 304 }); 305 } 306 }); 307 } 308 309 if (document.readyState === 'loading') { 310 document.addEventListener('DOMContentLoaded', init); 311 } else { 312 init(); 313 } 314 })(); 315 </script>
315<!-- Event Tracking -->
315<script> 316 (function() { 317 // GA4 Event Tracking via dataLayer 318 function trackEvent(eventName, eventParams) { 319 window.dataLayer = window.dataLayer || []; 320 window.dataLayer.push({ 321 event: eventName, 322 ...eventParams 323 }); 324 } 325 326 // Handle clicks on tracked elements 327 document.addEventListener('click', function(e) { 328 const tracked = e.target.closest('[data-track]'); 329 if (!tracked) return; 330 331 const eventName = tracked.dataset.track; 332 const params = {}; 333 334 // Collect all data-track-* attributes as event parameters 335 for (const attr of tracked.attributes) { 336 if (attr.name.startsWith('data-track-') && attr.name !== 'data-track') { 337 const paramName = attr.name.replace('data-track-', '').replace(/-/g, '_'); 338 params[paramName] = attr.value; 339 } 340 } 341 342 trackEvent(eventName, params); 343 }); 344 345 // Expose trackEvent globally for programmatic use (e.g., pricing toggle) 346 window.snapglyphTrack = trackEvent; 347 })(); 348 </script>
348</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.