On-Page SEO Myths: Google Rewards UX in 2026

Listen to this article · 9 min listen

There’s a staggering amount of misinformation out there regarding effective on-page SEO strategies, leading countless businesses down unproductive paths in their marketing efforts. So, how do you cut through the noise and ensure your website isn’t making fundamental errors that stifle its search visibility?

Key Takeaways

  • Prioritize user experience over keyword stuffing; Google’s algorithms heavily reward engaging, readable content.
  • Implement structured data markup using Schema.org to enhance rich snippets and provide context to search engines.
  • Focus on internal linking strategically, ensuring older, authoritative content passes “link juice” to newer, relevant pages.
  • Conduct thorough keyword research using tools like Semrush or Ahrefs to identify realistic target terms and user intent.

Myth #1: Keyword Density is Still King

The misconception that you need to hit a specific keyword density percentage for your content to rank is stubbornly persistent. I’ve heard clients (even in 2026!) ask if their page has “enough” keywords, often aiming for some arbitrary 2-3% figure. This idea is not only outdated but actively harmful. Google’s algorithms have evolved far beyond simple keyword counts. They prioritize natural language processing and understanding the context and relevance of your content.

We had a client last year, a local boutique in Atlanta’s Westside Provisions District, who was obsessed with stuffing “Atlanta boutique dresses” into every paragraph on their product pages. Their rankings were stagnant. After we convinced them to rewrite the descriptions to be more descriptive, engaging, and natural – focusing on fabric, style, and occasions, while still naturally including the core terms – their product pages started gaining traction. Within three months, their organic traffic from relevant searches for specific dress styles, not just generic terms, increased by 40%. The evidence is clear: focus on writing for your users first, and search engines will follow. According to a recent HubSpot report, content that is “highly relevant and user-centric” significantly outperforms keyword-stuffed pages in terms of engagement metrics, which Google interprets as quality signals.

Myth #2: Meta Descriptions Don’t Matter for SEO Anymore

“Meta descriptions aren’t a direct ranking factor,” someone might tell you, dismissing their importance entirely. While it’s true that Google doesn’t use the meta description text to directly influence your search ranking, ignoring them is a colossal mistake. Think of your meta description as your ad copy in the search results. It’s your precious 150-160 characters to entice a click. A well-crafted, compelling meta description can dramatically improve your click-through rate (CTR), and CTR is a strong indirect signal to search engines. If more people click on your result than a competitor’s, Google takes notice.

I always tell my team that a bland, auto-generated meta description is like having a storefront with a blank sign. Who’s going to walk in? We recently worked with an online furniture retailer based in Savannah. Their product pages had generic meta descriptions pulled directly from product titles. We rewrote 50 of their top-selling product meta descriptions, focusing on benefits, urgency, and including clear calls to action. For instance, for a sofa, instead of “Luxury Sofa,” it became “Experience unparalleled comfort with our handcrafted velvet sofa – free shipping nationwide!” Over the next quarter, these specific product pages saw an average 18% increase in CTR from organic search, directly leading to more traffic and sales. This isn’t just theory; it’s a measurable impact on your marketing performance.

Myth #3: H1 Tags Are Just for Looks

Some developers, and even some SEO “experts,” treat H1 tags as merely a stylistic choice, often making them identical to the page title or worse, omitting them entirely. This is a fundamental misunderstanding of their role. Your H1 tag is not just a big headline; it’s the most important on-page signal to search engines about the primary topic of your page. It tells Google, “This is what this page is fundamentally about.”

Imagine you’re a librarian. The H1 is like the main title on the spine of a book – it immediately tells you the book’s core subject. If it’s missing, or just says “Chapter 1,” it’s far less helpful. For effective on-page SEO, your H1 should contain your primary target keyword, be unique to the page, and accurately reflect the content that follows. I’ve seen countless websites where the H1 is completely different from the actual page title ( tag) or even missing. This creates confusion for both users and search engines. I firmly believe a properly optimized H1, distinct from the <title> tag but aligned with its intent, is non-negotiable for proper page indexing and topic understanding.</p> <aside class="related-callout"><span class="related-callout-label">Related Reading</span><a href="https://rankanddiscover.com/google-s-2026-dominance-why-on-page-seo-wins/">Google’s 2026 Dominance: Why On-Page SEO Wins</a></p> <p class="related-callout-excerpt">Understand the critical role of on-page SEO in securing top rankings on Google in the coming years.</p> </aside> <h2 id="section-5">Myth #4: Internal Linking Doesn’t Need a Strategy</h2> <p>“Just link to other pages on your site, it doesn’t really matter how.” This casual approach to <strong>internal linking</strong> is a huge missed opportunity in <strong>on-page SEO</strong>. Many think of internal links as just navigation, but they are powerful tools for distributing “link equity” (or “PageRank” as it was once known) throughout your site, signaling content relationships, and improving user experience. A strong internal linking strategy ensures that your most authoritative pages pass value to newer or less prominent, but important, content.</p> <p>We ran into this exact issue at my previous firm working with a large e-commerce client selling outdoor gear. Their blog had hundreds of articles, but new product pages rarely ranked well because they were essentially isolated. We implemented a systematic internal linking strategy: identifying relevant, high-authority blog posts and adding contextual links to related product pages, using descriptive <strong>anchor text</strong>. For example, a blog post about “The Best Hiking Trails in North Georgia” would link to specific hiking boot product pages. We also created “pillar pages” that linked out to numerous sub-topics. This structured approach led to a 25% increase in organic search visibility for their new product launches within six months, simply by better connecting their existing content. This wasn’t about building external links; it was purely about intelligent internal architecture.</p> <h2 id="section-6">Myth #5: Content Length is the Only Factor for Quality</h2> <p>The idea that “longer content always ranks better” is a dangerous oversimplification. While comprehensive content often performs well, simply adding more words without substance is a waste of time and resources. Google values <strong>quality and relevance</strong> above all else. A 500-word article that thoroughly answers a user’s query and provides unique insights will almost certainly outperform a 2000-word rambling piece that skirts around the topic.</p> <p>What matters is <strong>topical authority</strong> and <strong>completeness</strong>. Does your content cover the subject exhaustively without unnecessary fluff? Does it answer potential follow-up questions? Does it offer a unique perspective? I’ve seen plenty of examples where concise, well-structured content ranks higher than verbose, poorly organized articles. The average length of top-ranking content might be higher, but that’s a correlation, not causation. Those longer pieces tend to be more comprehensive, not just longer for the sake of it. Focus on providing genuine value and addressing user intent fully, whether that takes 700 words or 1500.</p> <p>Avoiding these common <a href="https://rankanddiscover.com/on-page-seo-dominate-2026-with-5-key-tactics/">on-page SEO mistakes</a> is not just about rankings; it’s about building a better user experience and a more robust digital presence for your <strong>marketing</strong> efforts. By focusing on user intent, strategic content structuring, and intelligent internal linking, you’ll set your website up for sustainable long-term success.</p> <div class="faq-section"> <div class="faq-item"> <h3 class="faq-question">What is “on-page SEO” exactly?</h3> <div class="faq-answer"> <p><strong>On-page SEO</strong> refers to all the optimization efforts you can make directly on your website’s pages to improve their search engine rankings. This includes optimizing content, HTML source code (like title tags and meta descriptions), and images, all with the goal of making the page more understandable and appealing to search engines and users.</p> </div> </div> <div class="faq-item"> <h3 class="faq-question">How often should I update my old content for SEO?</h3> <div class="faq-answer"> <p>You should aim to review and update your evergreen content at least once a year, or more frequently if the information changes rapidly in your industry. This process, often called <strong>content refreshing</strong>, helps maintain its relevance and authority, signaling to search engines that your site is a current and reliable source of information. I typically recommend setting a quarterly reminder for your top 20 most important pages.</p> </div> </div> <div class="faq-item"> <h3 class="faq-question">Does image optimization really impact on-page SEO?</h3> <div class="faq-answer"> <p>Absolutely. <strong>Image optimization</strong> is critical for both user experience and search engine visibility. Properly sized and compressed images improve page load speed, which is a direct ranking factor. Additionally, descriptive <strong>alt text</strong> provides context to search engines about the image content, making your page more accessible and discoverable for image searches. For example, instead of “image1.jpg,” use “red-velvet-sofa-living-room.jpg” with alt text “Luxurious red velvet sofa perfect for a modern living room.”</p> </div> </div> <div class="faq-item"> <h3 class="faq-question">What is structured data and why should I use it?</h3> <div class="faq-answer"> <p><strong>Structured data</strong>, often implemented using Schema.org vocabulary, is a standardized format for providing information about a webpage and its content. It helps search engines better understand the context of your content, which can lead to enhanced search results displays like <strong>rich snippets</strong> (e.g., star ratings, product prices, event dates). Implementing <a href="https://rankanddiscover.com/structured-data-marketing-2026-e-commerce-boost/">structured data</a> can significantly improve your visibility and click-through rates without directly impacting rankings. I consider it a must-have for any serious e-commerce or local business site.</p> </div> </div> <div class="faq-item"> <h3 class="faq-question">Should I use external links on my pages?</h3> <div class="faq-answer"> <p>Yes, strategically placed <strong>external links</strong> to high-authority, relevant sources can actually enhance your page’s credibility and topical authority. When you cite a reputable study or statistic, linking to the original source demonstrates thoroughness and provides additional value to your readers. It’s a signal to Google that your content is well-researched and trustworthy, which can indirectly benefit your <strong>on-page SEO</strong>.</p> </div> </div> </div> </div> <div class="share-buttons"> <span class="share-label">Share:</span> <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F" class="share-btn facebook" target="_blank" rel="noopener noreferrer" aria-label="Share on Facebook"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"/></svg> <span>Facebook</span> </a> <a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&text=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" class="share-btn twitter" target="_blank" rel="noopener noreferrer" aria-label="Share on Twitter"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg> <span>Twitter</span> </a> <a href="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&media=https%3A%2F%2Frankanddiscover.com%2Fwp-content%2Fuploads%2Fsites%2F30%2F2026%2F03%2Ftechnical-seo-in-2026-your-complete-marketing-guide-featured.png&description=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" class="share-btn pinterest" target="_blank" rel="noopener noreferrer" aria-label="Share on Pinterest"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.632-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg> <span>Pinterest</span> </a> <a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&title=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" class="share-btn linkedin" target="_blank" rel="noopener noreferrer" aria-label="Share on LinkedIn"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2zM4 6a2 2 0 100-4 2 2 0 000 4z"/></svg> <span>LinkedIn</span> </a> <button class="share-btn copy-link" onclick="navigator.clipboard.writeText('https://rankanddiscover.com/on-page-seo-myths-google-rewards-ux-in-2026/').then(function(){this.querySelector('span').textContent='Copied!'}.bind(this))"> <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/><path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg> <span>Copy Link</span> </button> </div> <div class="article-feedback" id="article-feedback"> <span class="feedback-question">Was this article helpful?</span> <button class="feedback-btn feedback-yes" data-vote="yes" aria-label="Yes"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z"/><path d="M7 22H4a2 2 0 01-2-2v-7a2 2 0 012-2h3"/></svg> Yes </button> <button class="feedback-btn feedback-no" data-vote="no" aria-label="No"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 15v4a3 3 0 003 3l4-9V2H5.72a2 2 0 00-2 1.7l-1.38 9a2 2 0 002 2.3H10z"/><path d="M17 2h2.67A2.31 2.31 0 0122 4v7a2.31 2.31 0 01-2.33 2H17"/></svg> No </button> </div> <script> (function(){ var fb = document.getElementById('article-feedback'); if(!fb) return; fb.querySelectorAll('.feedback-btn').forEach(function(btn){ btn.addEventListener('click', function(){ var vote = this.dataset.vote; fetch('/wp-json/satellite/v1/feedback', { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({post_id:14400,vote:vote}) }); fb.innerHTML = '<span class="feedback-thanks">Thanks for your feedback!</span>'; }); }); })(); </script> <div class="author-bio"> <div class="author-bio-avatar"> <img fetchpriority="low" loading="lazy" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png 2x' class='avatar avatar-72 photo' height='72' width='72' decoding='async'/> </div> <div class="author-bio-info"> <h4 class="author-bio-name"> <a href="https://rankanddiscover.com/author/rankanddkaimatsumoto/"> Kai Matsumoto </a> </h4> <span class="author-bio-title">Digital Marketing Strategist</span> <span class="author-bio-credentials">MBA, University of California, Berkeley; Google Ads Certified; Bing Ads Accredited Professional</span> <p class="author-bio-description">Kai Matsumoto is a seasoned Digital Marketing Strategist with 15 years of experience specializing in advanced SEO and SEM strategies. As the former Head of Search at Horizon Digital Group, he spearheaded campaigns that consistently delivered double-digit growth in organic traffic and conversion rates for Fortune 500 clients. Kai is particularly adept at leveraging AI-driven analytics for predictive keyword modeling and competitive intelligence. His insights have been featured in 'Search Engine Journal,' and he is recognized for his groundbreaking work in semantic search optimization</p> <div class="author-bio-links"> <a href="https://skillshop.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="author-link-badge"> Credentials </a> <span class="author-experience">15+ years experience</span> </div> </div> </div> </div> <aside class="single-post-sidebar"> <div class="sidebar-sticky"> <div class="sidebar-share"> <span class="sidebar-share-label">Share</span> <div class="sidebar-share-icons"> <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F" target="_blank" rel="noopener noreferrer" class="sidebar-share-icon facebook" aria-label="Facebook"> <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"/></svg> </a> <a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&text=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" target="_blank" rel="noopener noreferrer" class="sidebar-share-icon twitter" aria-label="Twitter"> <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg> </a> <a href="https://pinterest.com/pin/create/button/?url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&description=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" target="_blank" rel="noopener noreferrer" class="sidebar-share-icon pinterest" aria-label="Pinterest"> <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738a.36.36 0 01.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.632-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg> </a> <a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Frankanddiscover.com%2Fon-page-seo-myths-google-rewards-ux-in-2026%2F&title=On-Page+SEO+Myths%3A+Google+Rewards+UX+in+2026" target="_blank" rel="noopener noreferrer" class="sidebar-share-icon linkedin" aria-label="LinkedIn"> <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2zM4 6a2 2 0 100-4 2 2 0 000 4z"/></svg> </a> </div> </div> <div class="sidebar-top-posts"> <h3 class="sidebar-section-title">Top Posts</h3> <a href="https://rankanddiscover.com/ai-search-visibility-dominate-2026-with-brightedge/" class="sidebar-post-card"> <div class="sidebar-post-thumb"> <img width="300" height="200" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-300x200.webp?v=1776203161" class="attachment-satellite-thumb size-satellite-thumb wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-300x200.webp?v=1776203161 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-600x400.webp?v=1776203161 600w" sizes="auto, (max-width: 300px) 100vw, 300px" /> </div> <div class="sidebar-post-info"> <h4 class="sidebar-post-title">AI Search Visibility: Dominate 2026 with BrightEdge</h4> <div class="sidebar-post-meta"> <time datetime="2026-04-13T20:24:23+00:00">13/04/2026</time> <span class="sidebar-post-views">228 Views</span> </div> </div> </a> <a href="https://rankanddiscover.com/aeo-marketing-data-automation-for-2026-success/" class="sidebar-post-card"> <div class="sidebar-post-thumb"> <img width="300" height="200" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-300x200.webp?v=1773617301" class="attachment-satellite-thumb size-satellite-thumb wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-300x200.webp?v=1773617301 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-600x400.webp?v=1773617301 600w" sizes="auto, (max-width: 300px) 100vw, 300px" /> </div> <div class="sidebar-post-info"> <h4 class="sidebar-post-title">AEO Marketing: Data & Automation for 2026 Success</h4> <div class="sidebar-post-meta"> <time datetime="2026-03-15T23:28:21+00:00">15/03/2026</time> <span class="sidebar-post-views">208 Views</span> </div> </div> </a> <a href="https://rankanddiscover.com/keyword-strategy-in-2026-marketings-new-rules/" class="sidebar-post-card"> <div class="sidebar-post-thumb"> <img width="300" height="200" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/keyword-strategy-in-2026-marketing-s-new-rules-featured-300x200.webp?v=1773833559" class="attachment-satellite-thumb size-satellite-thumb wp-post-image" alt="" decoding="async" loading="lazy" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/keyword-strategy-in-2026-marketing-s-new-rules-featured-300x200.webp?v=1773833559 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/keyword-strategy-in-2026-marketing-s-new-rules-featured-600x400.webp?v=1773833559 600w" sizes="auto, (max-width: 300px) 100vw, 300px" /> </div> <div class="sidebar-post-info"> <h4 class="sidebar-post-title">Keyword Strategy in 2026: Marketing’s New Rules</h4> <div class="sidebar-post-meta"> <time datetime="2026-03-18T11:32:39+00:00">18/03/2026</time> <span class="sidebar-post-views">190 Views</span> </div> </div> </a> </div> </div> </aside> </div> <nav class="post-navigation"> <a href="https://rankanddiscover.com/content-optimization-techsolutions-2026-turnaround/" class="post-nav-link prev"> <div class="post-nav-label">« Previous</div> <div class="post-nav-title">Content Optimization: TechSolutions’ 2026 Turnaround</div> </a> <div></div> </nav> </article> <section class="related-posts"> <div class="section-header"> <h2 class="section-title">Related Articles</h2> <div class="carousel-nav"> <button class="carousel-btn carousel-prev" aria-label="Previous">‹</button> <button class="carousel-btn carousel-next" aria-label="Next">›</button> </div> </div> <div class="related-carousel" id="related-carousel"> <div class="carousel-track"> <article class="article-card"> <a href="https://rankanddiscover.com/keyword-strategy-5-myths-costing-you-in-2025/" class="article-card-image" aria-label="Keyword Strategy: 5 Myths Costing You in 2025"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-in-2026-ditch-the-myths-drive-real-traffic-featured-768x419.webp?v=1776683320" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-in-2026-ditch-the-myths-drive-real-traffic-featured-768x419.webp?v=1776683320 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-in-2026-ditch-the-myths-drive-real-traffic-featured-300x164.webp?v=1776683320 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-in-2026-ditch-the-myths-drive-real-traffic-featured-1024x559.webp?v=1776683320 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-in-2026-ditch-the-myths-drive-real-traffic-featured.webp?v=1776683320 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/seo-sem/" class="article-card-category" style="color:#334155"> SEO & SEM </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/keyword-strategy-5-myths-costing-you-in-2025/">Keyword Strategy: 5 Myths Costing You in 2025</a> </h3> <p class="article-card-excerpt">Listen to this article · 10 min listen1.0xAudio playback not supported in this browser.There’s an astonishing amount of misinformation circulating about effective keyword strategy in modern marketing,…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Kai Matsumoto</span> <span class="dot">·</span> <time datetime="2026-08-04T23:34:57+00:00">04/08/2026</time> <span class="dot">·</span> <span>8 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/google-trends-5-growth-hacks-for-2026/" class="article-card-image" aria-label="Google Trends: 5 Growth Hacks for 2026"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/2026-search-trends-marketing-s-future-is-here-featured-768x419.webp?v=1773615962" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/2026-search-trends-marketing-s-future-is-here-featured-768x419.webp?v=1773615962 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/2026-search-trends-marketing-s-future-is-here-featured-300x164.webp?v=1773615962 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/2026-search-trends-marketing-s-future-is-here-featured-1024x559.webp?v=1773615962 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/2026-search-trends-marketing-s-future-is-here-featured.webp?v=1773615962 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/seo-sem/" class="article-card-category" style="color:#334155"> SEO & SEM </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/google-trends-5-growth-hacks-for-2026/">Google Trends: 5 Growth Hacks for 2026</a> </h3> <p class="article-card-excerpt">Listen to this article · 13 min listen1.0xAudio playback not supported in this browser.Understanding search trends isn’t just about spotting what’s popular; it’s about predicting the future…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddkaimatsumoto-headshot-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Kai Matsumoto</span> <span class="dot">·</span> <time datetime="2026-08-04T17:35:13+00:00">04/08/2026</time> <span class="dot">·</span> <span>10 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/ai-search-visibility-dominate-2026-with-brightedge/" class="article-card-image" aria-label="AI Search Visibility: Dominate 2026 with BrightEdge"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-768x419.webp?v=1776203161" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-768x419.webp?v=1776203161 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-300x164.webp?v=1776203161 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured-1024x559.webp?v=1776203161 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/ai-search-visibility-dominate-2026-with-brightedge-featured.webp?v=1776203161 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/marketing-analytics/" class="article-card-category" style="color:#0369a1"> Marketing Analytics </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/ai-search-visibility-dominate-2026-with-brightedge/">AI Search Visibility: Dominate 2026 with BrightEdge</a> </h3> <p class="article-card-excerpt">Listen to this article · 10 min listen1.0xAudio playback not supported in this browser.Are you struggling to make your mark in the crowded digital space? Mastering AI…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjohnsmith-headshot-3-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjohnsmith-headshot-3-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Amanda Davis</span> <span class="dot">·</span> <time datetime="2026-04-13T20:24:23+00:00">13/04/2026</time> <span class="dot">·</span> <span>8 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/aeo-marketing-data-automation-for-2026-success/" class="article-card-image" aria-label="AEO Marketing: Data & Automation for 2026 Success"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-768x419.webp?v=1773617301" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-768x419.webp?v=1773617301 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-300x164.webp?v=1773617301 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured-1024x559.webp?v=1773617301 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/aeo-marketing-data-automation-for-2026-success-featured.webp?v=1773617301 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/marketing-tech/" class="article-card-category" style="color:#b13a1d"> Marketing Tech </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/aeo-marketing-data-automation-for-2026-success/">AEO Marketing: Data & Automation for 2026 Success</a> </h3> <p class="article-card-excerpt">Listen to this article · 7 min listen1.0xAudio playback not supported in this browser.Are you ready to take your aeo strategies to the next level? In the…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankandddavidlee-headshot-1-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankandddavidlee-headshot-1-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Amanda Gill</span> <span class="dot">·</span> <time datetime="2026-03-15T23:28:21+00:00">15/03/2026</time> <span class="dot">·</span> <span>6 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/content-optimization-techsolutions-2026-turnaround/" class="article-card-image" aria-label="Content Optimization: TechSolutions’ 2026 Turnaround"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-optimization-the-2026-marketing-advantage-featured-768x419.webp?v=1775802401" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-optimization-the-2026-marketing-advantage-featured-768x419.webp?v=1775802401 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-optimization-the-2026-marketing-advantage-featured-300x164.webp?v=1775802401 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-optimization-the-2026-marketing-advantage-featured-1024x559.webp?v=1775802401 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-optimization-the-2026-marketing-advantage-featured.webp?v=1775802401 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/content-strategy/" class="article-card-category" style="color:#be185d"> Content Strategy </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/content-optimization-techsolutions-2026-turnaround/">Content Optimization: TechSolutions’ 2026 Turnaround</a> </h3> <p class="article-card-excerpt">Listen to this article · 10 min listen1.0xAudio playback not supported in this browser.The digital marketing world demands more than just creating content; it demands content that…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddniaokafor-headshot-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/rankanddniaokafor-headshot-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Dawn Moore</span> <span class="dot">·</span> <time datetime="2026-08-05T03:09:09+00:00">05/08/2026</time> <span class="dot">·</span> <span>8 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/aeo-synapse-connect-s-25-roas-boost-in-2026/" class="article-card-image" aria-label="AEO: Synapse Connect’s 25% ROAS Boost in 2026"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/aeo-stop-wasting-ad-spend-in-2026-featured-768x419.webp?v=1775628695" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/aeo-stop-wasting-ad-spend-in-2026-featured-768x419.webp?v=1775628695 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/aeo-stop-wasting-ad-spend-in-2026-featured-300x164.webp?v=1775628695 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/aeo-stop-wasting-ad-spend-in-2026-featured-1024x559.webp?v=1775628695 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/aeo-stop-wasting-ad-spend-in-2026-featured.webp?v=1775628695 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/digital-marketing/" class="article-card-category" style="color:#9a3412"> Digital Marketing </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/aeo-synapse-connect-s-25-roas-boost-in-2026/">AEO: Synapse Connect’s 25% ROAS Boost in 2026</a> </h3> <p class="article-card-excerpt">Listen to this article · 11 min listen1.0xAudio playback not supported in this browser.Achieving success in today’s crowded digital space demands more than just throwing money at…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankandddavidlee-headshot-1-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankandddavidlee-headshot-1-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Amanda Gill</span> <span class="dot">·</span> <time datetime="2026-08-05T02:22:58+00:00">05/08/2026</time> <span class="dot">·</span> <span>8 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/content-strategy-stop-wasting-ad-dollars-in-2026/" class="article-card-image" aria-label="Content Strategy: Stop Wasting Ad Dollars in 2026"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-strategy-stop-wasting-ad-dollars-in-2026-featured-768x419.webp?v=1776269701" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-strategy-stop-wasting-ad-dollars-in-2026-featured-768x419.webp?v=1776269701 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-strategy-stop-wasting-ad-dollars-in-2026-featured-300x164.webp?v=1776269701 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-strategy-stop-wasting-ad-dollars-in-2026-featured-1024x559.webp?v=1776269701 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/content-strategy-stop-wasting-ad-dollars-in-2026-featured.webp?v=1776269701 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/marketing-analytics/" class="article-card-category" style="color:#0369a1"> Marketing Analytics </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/content-strategy-stop-wasting-ad-dollars-in-2026/">Content Strategy: Stop Wasting Ad Dollars in 2026</a> </h3> <p class="article-card-excerpt">Listen to this article · 7 min listen1.0xAudio playback not supported in this browser.Content strategy matters more than ever in 2026. The digital space is saturated, and…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjohnsmith-headshot-3-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjohnsmith-headshot-3-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Amanda Davis</span> <span class="dot">·</span> <time datetime="2026-04-15T13:51:28+00:00">15/04/2026</time> <span class="dot">·</span> <span>6 min read</span> </div> </div> </article> <article class="article-card"> <a href="https://rankanddiscover.com/seo-ai-escape-the-algorithm-abyss-in-2026/" class="article-card-image" aria-label="SEO & AI: Escape the Algorithm Abyss in 2026"> <img width="768" height="419" src="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-ai-escape-the-algorithm-abyss-in-2026-featured-768x419.webp?v=1776694732" class="attachment-medium_large size-medium_large wp-post-image" alt="" loading="lazy" decoding="async" srcset="https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-ai-escape-the-algorithm-abyss-in-2026-featured-768x419.webp?v=1776694732 768w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-ai-escape-the-algorithm-abyss-in-2026-featured-300x164.webp?v=1776694732 300w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-ai-escape-the-algorithm-abyss-in-2026-featured-1024x559.webp?v=1776694732 1024w, https://rankanddiscover.com/wp-content/uploads/sites/30/2026/04/seo-ai-escape-the-algorithm-abyss-in-2026-featured.webp?v=1776694732 1408w" sizes="auto, (max-width: 768px) 100vw, 768px" /> </a> <div class="article-card-body"> <a href="https://rankanddiscover.com/category/marketing-tech/" class="article-card-category" style="color:#b13a1d"> Marketing Tech </a> <h3 class="article-card-title"> <a href="https://rankanddiscover.com/seo-ai-escape-the-algorithm-abyss-in-2026/">SEO & AI: Escape the Algorithm Abyss in 2026</a> </h3> <p class="article-card-excerpt">Listen to this article · 11 min listen1.0xAudio playback not supported in this browser.Are you struggling to make your brand visible across the vast digital ocean, feeling…</p> <div class="article-card-meta"> <img fetchpriority="low" alt='' src='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjanedoe-headshot-1-150x150.png' srcset='https://rankanddiscover.com/wp-content/uploads/sites/30/2026/03/rankanddjanedoe-headshot-1-150x150.png 2x' class='avatar avatar-22 photo' height='22' width='22' loading='lazy' decoding='async'/> <span class="author-name">Amanda Clarke</span> <span class="dot">·</span> <time datetime="2026-04-20T18:03:40+00:00">20/04/2026</time> <span class="dot">·</span> <span>9 min read</span> </div> </div> </article> </div> </div> </section> <script> (function(){ var track = document.querySelector('.carousel-track'); if(!track) return; var prev = document.querySelector('.carousel-prev'); var next = document.querySelector('.carousel-next'); var cardW = track.querySelector('.article-card'); if(!cardW) return; var scrollAmt = cardW.offsetWidth + 24; if(prev) prev.addEventListener('click', function(){ track.scrollBy({left:-scrollAmt,behavior:'smooth'}); }); if(next) next.addEventListener('click', function(){ track.scrollBy({left:scrollAmt,behavior:'smooth'}); }); })(); </script> </main> </div> </div><!-- .container --> <footer class="site-footer" role="contentinfo"> <div class="footer-main"> <div class="footer-col footer-about"> <div class="widget"> <h3 class="widget-title">Rank & Discover</h3> <p>Expert insights, guides, and stories about marketing</p> </div> </div> <div class="footer-col"> <div class="widget"> <h3 class="widget-title">Categories</h3> <ul> <li class="cat-item cat-item-25"><a href="https://rankanddiscover.com/category/campaign-insights/">Campaign Insights</a> </li> <li class="cat-item cat-item-19"><a href="https://rankanddiscover.com/category/content-strategy/">Content Strategy</a> </li> <li class="cat-item cat-item-21"><a href="https://rankanddiscover.com/category/customer-experience/">Customer Experience</a> </li> <li class="cat-item cat-item-18"><a href="https://rankanddiscover.com/category/digital-marketing/">Digital Marketing</a> </li> <li class="cat-item cat-item-20"><a href="https://rankanddiscover.com/category/marketing-analytics/">Marketing Analytics</a> </li> <li class="cat-item cat-item-24"><a href="https://rankanddiscover.com/category/marketing-tech/">Marketing Tech</a> </li> <li class="cat-item cat-item-23"><a href="https://rankanddiscover.com/category/seo-sem/">SEO & SEM</a> </li> <li class="cat-item cat-item-22"><a href="https://rankanddiscover.com/category/social-media/">Social Media</a> </li> </ul> </div> </div> <div class="footer-col"> <div class="widget"> <h3 class="widget-title">Quick Links</h3> <ul> <li><a href="https://rankanddiscover.com/">Home</a></li> <li><a href="https://rankanddiscover.com/editorial-standards/">Editorial Standards</a></li> <li><a href="https://rankanddiscover.com/about/">About</a></li> <li><a href="https://rankanddiscover.com/contact/">Contact</a></li> <li><a href="https://rankanddiscover.com/privacy-policy/">Privacy Policy</a></li> <li><a href="https://rankanddiscover.com/terms-of-service/">Terms of Service</a></li> </ul> </div> </div> <div class="footer-col footer-col-authors"> <div class="widget"> <h3 class="widget-title">Our Authors</h3> <ul class="footer-authors-list" style="columns: 2; -webkit-columns: 2; -moz-columns: 2; column-gap: 1.5rem; padding-left: 0; list-style: none; margin: 0;"> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankandddevinchandra/">Deborah Santos</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkevinbrown/">Anne Hart</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjohnsmith/">Amanda Davis</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjamaladeyemi/">Deanna Mitchell</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddlenakimani/">Dawn Johnson</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddnaoiseoconnell/">Naoise OConnell</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkaimatsumoto/">Kai Matsumoto</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkiarandlovu/">Kiara Ndlovu</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjanedoe/">Amanda Clarke</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddanyasharma/">Dawn Coleman</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddmarcuskim/">Debra Cook</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddrenatachung/">Debbie Henderson</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjamilaowusu/">Deborah Ferguson</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddmateochavez/">Debbie Cline</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddlenaokoro/">Debra Chavez</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjennifermurray/">Jennifer Murray</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankandddavidlee/">Amanda Gill</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddseraphinacruz/">Seraphina Cruz</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddmarcuschen/">Dawn Ross</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddzarakhan/">Deanna Hicks</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkeishadubois/">Deanna Barry</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkeonvelasquez/">Keon Velasquez</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjenniferobrien/">Jennifer Obrien</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkeatonadetunji/">Keaton Adetunji</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjaviermontoya/">David Willis</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddrorychung/">Deborah Lynch</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddashleywilson/">Anne Merritt</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddjennifermcdonald/">Jennifer Mcdonald</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddkeishamontgomery/">Debra Christian</a></li> <li style="break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid; padding: 2px 0;"><a href="https://rankanddiscover.com/author/rankanddmariagarcia/">Amanda Erickson</a></li> </ul> </div> </div> </div> <div class="footer-bottom"> <div class="footer-bottom-inner"> <div class="footer-copyright"> © 2026 Rank & Discover. All rights reserved. </div> <nav class="footer-nav" role="navigation"> </nav> </div> </div> </footer> <script id="sat-tts-script"> (function(){ if (!('speechSynthesis' in window) || !('SpeechSynthesisUtterance' in window)) { document.querySelectorAll('.sat-tts-player').forEach(function(el){ el.setAttribute('data-state', 'unsupported'); var t = el.querySelector('.sat-tts-title-text'); var i18n = el.querySelector('.sat-tts-i18n'); if (t && i18n) t.textContent = i18n.dataset.unsupported; }); return; } var player = document.querySelector('.sat-tts-player[data-sat-tts]'); if (!player) return; var contentRoot = document.querySelector('.post-content') || document.querySelector('article .single-post-main') || document.querySelector('article'); if (!contentRoot) return; var toggleBtn = player.querySelector('.sat-tts-toggle'); var rateBtn = player.querySelector('.sat-tts-rate'); var titleText = player.querySelector('.sat-tts-title-text'); var progressEl = player.querySelector('.sat-tts-progress-fill'); var i18n = player.querySelector('.sat-tts-i18n'); var STORAGE_KEY = 'sat_tts_v1_' + (location.pathname || '/'); var RATE_CYCLE = [1, 1.25, 1.5, 2, 0.85]; // ── Build chunks ───────────────────────────────────────────── // Strip HTML to a clean, sequential text array. We skip elements // that read awkwardly aloud (figures, embedded video/audio, the // related-callout sidebars, FAQ schema-heavy sections, code). function buildChunks(root) { var clone = root.cloneNode(true); // Remove things we never want spoken. clone.querySelectorAll( 'script,style,figure,iframe,video,audio,svg,noscript,' + 'aside,.related-callout,.sidebar-share,.sat-tts-player,' + '.article-feedback,.author-bio,.post-tags,.read-next-bar,' + '.post-navigation,.related-posts,form,nav,.toc-container' ).forEach(function(n){ n.parentNode && n.parentNode.removeChild(n); }); var blockSel = 'h1,h2,h3,h4,h5,h6,p,li,blockquote,td,th,dt,dd'; var blocks = clone.querySelectorAll(blockSel); var chunks = []; blocks.forEach(function(b){ var t = (b.textContent || '').replace(/\s+/g, ' ').trim(); if (!t) return; // Long paragraphs: break on sentence boundaries so Chrome // doesn't silently drop after ~15s of a single utterance. if (t.length > 220) { var sentences = t.match(/[^.!?]+[.!?]+(?:\s|$)|[^.!?]+$/g) || [t]; var buf = ''; sentences.forEach(function(s){ s = s.trim(); if (!s) return; if ((buf + ' ' + s).trim().length > 220 && buf) { chunks.push(buf.trim()); buf = s; } else { buf = (buf ? buf + ' ' : '') + s; } }); if (buf.trim()) chunks.push(buf.trim()); } else { chunks.push(t); } }); return chunks; } var chunks = buildChunks(contentRoot); if (chunks.length === 0) return; var totalChars = chunks.reduce(function(a,c){ return a + c.length; }, 0); // ── State machine ─────────────────────────────────────────── var state = { playing: false, paused: false, chunkIndex: 0, charsSpoken: 0, rate: 1, voice: null, currentUtter: null, }; try { var saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null'); if (saved && typeof saved.chunkIndex === 'number' && saved.chunkIndex < chunks.length) { state.chunkIndex = saved.chunkIndex; state.charsSpoken = saved.charsSpoken || 0; state.rate = saved.rate || 1; } } catch (e) {} applyRate(state.rate); updateProgress(); // ── Voice selection ───────────────────────────────────────── // speechSynthesis populates voices async on most browsers. The // picker: // 1. filters by html lang prefix (en/es/...) // 2. drops novelty/character voices (Apple ships ~30 of them // and they sort BEFORE the natural ones on macOS, which is // why an unguarded pool[0] fallback ends up reading // Spanish articles in Eddy/Flo/Reed instead of Mónica) // 3. ranks survivors by an explicit per-language preference // list of high-quality voices, with a fallback that prefers // `localService` (built-in premium) over remote voices. var NOVELTY_NAME_RE = /^(Albert|Bad News|Bahh|Bells|Boing|Bubbles|Cellos|Deranged|Good News|Hysterical|Pipe Organ|Trinoids|Whisper|Wobble|Zarvox|Eddy|Flo|Grandma|Grandpa|Jester|Junior|Kathy|Organ|Princess|Ralph|Reed|Rocko|Sandy|Shelley|Superstar|Vicki|Victoria|Bahh|Boing|Cellos)\b/i; var PREFERRED_BY_LANG = { es: [ // macOS / iOS premium Spanish voices (best quality) /^M[oó]nica/i, // es-ES, very natural /^Paulina/i, // es-MX, very natural /^Jorge\b/i, // es-ES /^Diego\b/i, // es-AR /^Juan\b/i, // Microsoft Edge / Windows neural Spanish voices /Microsoft.*\b(Elvira|Dalia|Alvaro|Jorge|Helena|Sabina)\b.*Online/i, /Microsoft.*\b(Elvira|Dalia|Alvaro)\b/i, // Google Spanish (Chrome desktop, Android) /^Google\s+espa[ñn]ol(?:\s+de\s+(?:M[eé]xico|Estados Unidos))?$/i, /^Google\s+espa[ñn]ol/i, ], en: [ /^Google\s.*(US|UK|English)/i, /^Microsoft.*(Aria|Jenny|Guy|Ryan|Davis)\b.*Online/i, /^Microsoft.*(Aria|Jenny|Guy|Ryan|Davis)\b/i, /^Samantha$/i, /^Alex$/i, /English/i, ], }; function scoreVoice(v, preferredList) { for (var i = 0; i < preferredList.length; i++) { if (preferredList[i].test(v.name)) { // Earlier list entries score higher. localService gets a // small bump so a built-in voice wins over a remote one // when both match the same pattern. return 1000 - i * 10 + (v.localService ? 1 : 0); } } // No name match — still prefer non-novelty + localService. return (v.localService ? 1 : 0); } function pickVoice() { var voices = speechSynthesis.getVoices() || []; if (voices.length === 0) return null; var lang = (document.documentElement.lang || 'en').toLowerCase().split('-')[0]; var pool = voices.filter(function(v){ return (v.lang || '').toLowerCase().indexOf(lang) === 0; }); if (pool.length === 0) pool = voices; // Strip novelty voices unless that leaves us with nothing. var filtered = pool.filter(function(v){ return !NOVELTY_NAME_RE.test(v.name); }); if (filtered.length > 0) pool = filtered; var preferredList = PREFERRED_BY_LANG[lang] || PREFERRED_BY_LANG.en; var best = null, bestScore = -Infinity; pool.forEach(function(v){ var s = scoreVoice(v, preferredList); if (s > bestScore) { bestScore = s; best = v; } }); return best || pool[0]; } if (typeof speechSynthesis.addEventListener === 'function') { speechSynthesis.addEventListener('voiceschanged', function(){ state.voice = pickVoice(); }); } state.voice = pickVoice(); // ── Utterance queue ───────────────────────────────────────── function speakNext() { if (state.chunkIndex >= chunks.length) { stopAll(true); return; } var u = new SpeechSynthesisUtterance(chunks[state.chunkIndex]); u.rate = state.rate; u.pitch = 1; u.volume = 1; // Setting `lang` explicitly is what triggers the Spanish // synthesis backend on Chrome/Edge (which shipped neural // Spanish voices that aren't always exposed via getVoices // until referenced). When `voice` is set we prefer the // voice's own lang to avoid a mismatch. if (state.voice) { u.voice = state.voice; if (state.voice.lang) u.lang = state.voice.lang; } else { u.lang = (document.documentElement.lang || 'en'); } u.onend = function() { if (!state.playing) return; state.charsSpoken += chunks[state.chunkIndex].length; state.chunkIndex += 1; persist(); updateProgress(); if (state.chunkIndex < chunks.length) { speakNext(); } else { stopAll(true); } }; u.onerror = function(ev) { if (ev && ev.error === 'interrupted') return; state.playing = false; state.paused = false; state.currentUtter = null; renderState(); }; u.onboundary = function(ev) { if (ev && typeof ev.charIndex === 'number') { var partial = state.charsSpoken + Math.min(ev.charIndex, chunks[state.chunkIndex].length); var pct = Math.min(100, (partial / totalChars) * 100); progressEl.style.width = pct + '%'; } }; state.currentUtter = u; speechSynthesis.speak(u); } function play() { if (state.paused) { speechSynthesis.resume(); state.paused = false; state.playing = true; renderState(); return; } // Some browsers leave the queue stuck after a previous error; // cancel before starting fresh. try { speechSynthesis.cancel(); } catch (e) {} state.playing = true; state.paused = false; renderState(); speakNext(); } function pause() { if (!state.playing) return; try { speechSynthesis.pause(); } catch (e) {} state.paused = true; state.playing = false; persist(); renderState(); } function stopAll(reset) { try { speechSynthesis.cancel(); } catch (e) {} state.playing = false; state.paused = false; state.currentUtter = null; if (reset) { state.chunkIndex = 0; state.charsSpoken = 0; progressEl.style.width = '0%'; try { localStorage.removeItem(STORAGE_KEY); } catch (e) {} } renderState(); } // ── Rate cycle ───────────────────────────────────────────── function applyRate(r) { state.rate = r; rateBtn.textContent = r.toFixed(2).replace(/\.?0+$/, '') + 'x'; persist(); } rateBtn.addEventListener('click', function(){ var i = RATE_CYCLE.indexOf(state.rate); var next = RATE_CYCLE[(i + 1) % RATE_CYCLE.length]; applyRate(next); // If currently playing, restart the current chunk at the // new rate (Web Speech doesn't let you change rate mid-utter). if (state.playing && state.currentUtter) { stopAll(false); state.playing = true; renderState(); speakNext(); } }); toggleBtn.addEventListener('click', function(){ if (state.playing) { pause(); } else { play(); } }); // ── Chrome 15-second cutoff workaround ───────────────────── // Chrome stops Web Speech after ~15s of continuous output. We // ping pause+resume every 10s while playing to keep the queue // alive. Harmless on browsers that don't need it. setInterval(function(){ if (state.playing && !state.paused) { try { speechSynthesis.pause(); speechSynthesis.resume(); } catch (e) {} } }, 10000); // ── Persistence + UI ─────────────────────────────────────── function persist() { try { localStorage.setItem(STORAGE_KEY, JSON.stringify({ chunkIndex: state.chunkIndex, charsSpoken: state.charsSpoken, rate: state.rate, })); } catch (e) {} } function updateProgress() { var pct = totalChars ? Math.min(100, (state.charsSpoken / totalChars) * 100) : 0; progressEl.style.width = pct + '%'; } function renderState() { if (!i18n) return; if (state.playing) { player.setAttribute('data-state', 'playing'); titleText.textContent = i18n.dataset.playing; toggleBtn.setAttribute('aria-label', 'Pause'); } else if (state.paused) { player.setAttribute('data-state', 'paused'); titleText.textContent = i18n.dataset.paused; toggleBtn.setAttribute('aria-label', 'Resume'); } else { player.removeAttribute('data-state'); titleText.textContent = i18n.dataset.listen; toggleBtn.setAttribute('aria-label', 'Play'); } } // ── GA4 listen events ───────────────────────────────────── // Fire a small custom event the first time a visitor presses // play, so we can answer "does the listen button move // engagement?" from the analytics dashboard. var firedFirstPlay = false; toggleBtn.addEventListener('click', function(){ if (firedFirstPlay) return; if (typeof window.gtag === 'function') { try { window.gtag('event', 'tts_listen_play', { event_category: 'engagement', event_label: location.pathname, value: 1, }); } catch (e) {} } firedFirstPlay = true; }); // Stop speech when the visitor leaves the page so it doesn't // continue narrating in the background after navigation. window.addEventListener('beforeunload', function(){ try { speechSynthesis.cancel(); } catch (e) {} }); })(); </script> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/sites/30/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/satellite-theme/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script id="satellite-main-js-extra"> var satelliteAjax = {"ajaxurl":"https://rankanddiscover.com/wp-admin/admin-ajax.php","nonce":"1670f4aa03"}; //# sourceURL=satellite-main-js-extra </script> <script src="https://rankanddiscover.com/wp-content/themes/satellite-theme/assets/js/main.js?ver=4.10.1" id="satellite-main-js"></script> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=DM+Mono:wght@400;500&display=swap"></noscript> <style id="aeo-popup-styles"> #aeo-popup-root { --accent: #E8471A; --accent-dim: #C93C12; --accent-mid: #F07040; --accent-soft: #F9A07A; --card-bg: linear-gradient(105deg, #ffffff 0%, #fff4f0 40%, #ffeee7 70%, #ffffff 100%); --card-fade: #fff8f5; --bar-bg: linear-gradient(105deg, #ffffff 0%, #fff4f0 40%, #ffeee7 70%, #ffffff 100%); --cta-grad: linear-gradient(90deg, #E8471A 0%, #F07040 50%, #E8471A 100%); --cta-text: #ffffff; --shadow-rgb: 232,71,26; --ink: #111111; --ink-soft: #555555; --ink-faint: #999999; --border: #E2E4DC; --banner-h: 88px; /* "Google Sans" is in the stack as the brand fallback for installs that have it locally (e.g. internal Google environments); Inter is the loaded webfont and the de-facto free substitute. */ --font-display: 'Inter', 'Google Sans', system-ui, sans-serif; --font-body: 'Inter', 'Google Sans', system-ui, sans-serif; --font-mono: 'DM Mono', ui-monospace, Menlo, monospace; } #aeo-popup-root, #aeo-popup-root * { box-sizing: border-box; } @keyframes aeoPulse { 0%,100% { opacity:1; transform:scale(1); } 50% { opacity:.4; transform:scale(.7); } } @keyframes aeoCtaShimmer { 0% { background-position:0% 0%; } 50% { background-position:100% 0%; } 100% { background-position:0% 0%; } } @keyframes aeoBannerBreathe{ 0% { background-position:0% 50%; } 50% { background-position:100% 50%; } 100% { background-position:0% 50%; } } @keyframes aeoCardSlideUp { to { transform: translateY(0); opacity: 1; } } @keyframes aeoCardSlideDown{ to { transform: translateY(calc(100% + 32px)); opacity: 0; } } @keyframes aeoBarSlideUp { to { transform: translateY(0); opacity: 1; } } @keyframes aeoScTicker { 0% { transform: translateX(0); } 100% { transform: translateX(-33.3333%); } } /* ── STICKY CARD (bottom-left, initial state) ────────────────────── Default state is hidden -- JS adds .aeo-iframe-ready on the root once the modal iframe has finished loading in the background (or after a safety timeout), so the slide-up coincides with the funnel being click-ready. */ #aeo-popup-root .sticky-card { position: fixed; bottom: 24px; left: 24px; z-index: 9990; width: 340px; border-radius: 16px; overflow: hidden; border: 1px solid var(--border); box-shadow: 0 8px 40px rgba(var(--shadow-rgb),0.15), 0 2px 8px rgba(0,0,0,0.07); background: var(--card-bg); background-size: 300% 300%; transform: translateY(calc(100% + 32px)); opacity: 0; } #aeo-popup-root.aeo-iframe-ready .sticky-card { animation: aeoCardSlideUp 0.6s cubic-bezier(0.22,1,0.36,1) forwards, aeoBannerBreathe 5s ease-in-out 0.6s infinite; } #aeo-popup-root.aeo-skip-card .sticky-card { display: none; } #aeo-popup-root.aeo-lead-done .sticky-card, #aeo-popup-root.aeo-lead-done .sticky-banner { display: none; } #aeo-popup-root .sticky-card.hiding { animation: aeoCardSlideDown 0.4s cubic-bezier(0.4,0,1,1) forwards !important; } /* ── Border Beam ─────────────────────────────────────── A bright accent-coloured "comet" travels around the card perimeter. Implemented as a single ::before pseudo-element: 1. conic-gradient paints the comet (transparent for ~75% of the circle, then a soft -> bright -> soft fade across the last ~100°), 2. mask-composite:exclude cuts the inside out so only a 2px ring remains -- the comet appears to glide along the border, 3. @property animates the gradient's `from` angle so the rotation is on the gradient itself, not via transform (no sub-pixel shimmer, no GPU compositing cost, and the corners stay sharp). Browsers without @property (older Firefox <128, older Safari <16.4) render the gradient statically -- graceful degradation. */ @property --aeo-beam-angle { syntax: '<angle>'; initial-value: 0deg; inherits: false; } #aeo-popup-root .sticky-card::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 2px; background: conic-gradient( from var(--aeo-beam-angle), transparent 0deg, transparent 250deg, var(--accent-soft) 305deg, var(--accent) 340deg, var(--accent-soft) 360deg ); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none; z-index: 1; opacity: 0; transition: opacity .4s ease; } #aeo-popup-root.aeo-iframe-ready .sticky-card::before { opacity: 1; animation: aeoBeamRotate 5s linear infinite; } @keyframes aeoBeamRotate { to { --aeo-beam-angle: 360deg; } } #aeo-popup-root .sc-inner { padding: 18px 18px 20px; } #aeo-popup-root .sc-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; } #aeo-popup-root .sc-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-dim); display: flex; align-items: center; gap: 6px; } #aeo-popup-root .sc-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: aeoPulse 2s ease-in-out infinite; flex-shrink: 0; } #aeo-popup-root .sc-close { width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--border); background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--ink-faint); font-size: 16px; line-height: 1; transition: border-color .2s, color .2s, background .2s; flex-shrink: 0; padding: 0; } #aeo-popup-root .sc-close:hover { border-color: var(--ink); color: var(--ink); background: #F5F6F2; } #aeo-popup-root .sc-headline { font-family: var(--font-display); font-size: 19px; font-weight: 800; color: var(--ink); letter-spacing: -0.4px; line-height: 1.25; margin: 0 0 8px; } #aeo-popup-root .sc-sub { font-size: 13px; color: var(--ink-faint); line-height: 1.5; margin: 0 0 12px; font-family: var(--font-body); } #aeo-popup-root .sc-ticker-wrap { position: relative; overflow: hidden; margin-bottom: 14px; height: 28px; } #aeo-popup-root .sc-ticker-wrap::before, #aeo-popup-root .sc-ticker-wrap::after { content: ''; position: absolute; inset-block: 0; width: 20px; z-index: 2; pointer-events: none; } #aeo-popup-root .sc-ticker-wrap::before { left: 0; background: linear-gradient(to right, var(--card-fade), transparent); } #aeo-popup-root .sc-ticker-wrap::after { right: 0; background: linear-gradient(to left, var(--card-fade), transparent); } #aeo-popup-root .sc-ticker { /* Marquee math (do not change without revisiting both this rule AND the aeoScTicker keyframe + the JS that builds the chip list): - Each chip is 28px wide with an 8px trailing margin = 36px slot. - We render 3 copies of the 6-engine ticker = 18 chips = 648px. - One copy width = 6 * 36 = 216px = exactly 1/3 of the total. - The keyframe translates -33.3333% (= -216px), so the moment the first copy finishes scrolling out, the second copy is already occupying its exact original position. Seamless loop. We use margin-right on the chip (not flex gap) on purpose: flex gap only sits *between* siblings, which is one short for the cycle to line up with translateX. margin-right counts on every chip, so the total width is N*(chip+gap) and -1/N translation hits the boundary cleanly. Three copies is also what keeps the right edge of the card from ever going empty mid-scroll -- a single copy (216px) is narrower than the visible card content area, so doubled content would leave a gap on the right at the end of every cycle. */ display: flex; width: max-content; animation: aeoScTicker 18s linear infinite; align-items: center; height: 100%; } #aeo-popup-root .sc-logo-chip { width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0; margin-right: 8px; display: flex; align-items: center; justify-content: center; overflow: hidden; /* Faint inset border. On dark/coloured chips it's invisible; on the white Copilot chip it's what keeps the icon from floating against the light card background. */ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06); } #aeo-popup-root .sc-logo-chip img { width: 18px; height: 18px; object-fit: contain; display: block; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.15)); } /* Copilot-specific override: Microsoft's multicolor ribbon mark has finer detail than any of the other engines' marks (which are single- colour silhouettes), and its lighter gradient tips (cyan, yellow, pink) wash out at small sizes on a white chip. Bumping the image to nearly fill the 28px chip restores legibility. We target by [title] so future engine additions don't accidentally pick this up. */ #aeo-popup-root .sc-logo-chip[title="Copilot"] img { width: 24px; height: 24px; /* No drop-shadow on the Copilot icon -- the soft glow muddies the gradient ribbon. */ filter: none; } #aeo-popup-root .sc-cta { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; font-family: var(--font-body); font-size: 14px; font-weight: 600; color: var(--cta-text); background: var(--cta-grad); background-size: 200% 100%; border: none; border-radius: 100px; padding: 11px 20px; cursor: pointer; text-decoration: none; animation: aeoCtaShimmer 3s ease-in-out 2.4s infinite; transition: transform .15s, box-shadow .2s; } #aeo-popup-root .sc-cta:hover { transform: scale(1.02); box-shadow: 0 4px 20px rgba(var(--shadow-rgb),0.4); animation-play-state: paused; } #aeo-popup-root .sc-cta .arrow { font-size: 15px; transition: transform .2s; } #aeo-popup-root .sc-cta:hover .arrow { transform: translateX(3px); } /* ── STICKY BAR (after card dismissed) ──────────────────────────── */ #aeo-popup-root .sticky-banner { position: fixed; bottom: 0; left: 0; right: 0; z-index: 9990; transform: translateY(100%); opacity: 0; pointer-events: none; background: var(--bar-bg); background-size: 300% 300%; border-top: 1px solid var(--border); box-shadow: 0 -4px 32px rgba(var(--shadow-rgb),0.08), 0 -1px 0 rgba(var(--shadow-rgb),0.15); } #aeo-popup-root .sticky-banner.visible { pointer-events: all; animation: aeoBarSlideUp 0.5s cubic-bezier(0.22,1,0.36,1) forwards, aeoBannerBreathe 5s ease-in-out 0.5s infinite; } #aeo-popup-root .sticky-banner::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, var(--accent) 0%, var(--accent-soft) 60%, transparent 100%); } #aeo-popup-root .banner-inner { max-width: 1240px; margin: 0 auto; padding: 0 32px; height: var(--banner-h); display: flex; align-items: center; gap: 24px; } #aeo-popup-root .banner-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-dim); white-space: nowrap; flex-shrink: 0; display: flex; align-items: center; gap: 6px; } #aeo-popup-root .banner-label::before { content: ''; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: aeoPulse 2s ease-in-out infinite; } #aeo-popup-root .banner-divider-v { width: 1px; height: 32px; background: var(--border); flex-shrink: 0; } #aeo-popup-root .banner-headline { font-family: var(--font-display); font-size: 15px; font-weight: 800; color: var(--ink); letter-spacing: -0.3px; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; } #aeo-popup-root .banner-sub { font-size: 13px; color: var(--ink-faint); flex-shrink: 0; white-space: nowrap; font-family: var(--font-body); } #aeo-popup-root .banner-cta { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-body); font-size: 14px; font-weight: 600; color: var(--cta-text); background: var(--cta-grad); background-size: 200% 100%; border: none; border-radius: 100px; padding: 11px 28px; cursor: pointer; text-decoration: none; white-space: nowrap; flex-shrink: 0; animation: aeoCtaShimmer 3s ease-in-out 0.5s infinite; transition: transform .15s, box-shadow .2s; } #aeo-popup-root .banner-cta:hover { transform: scale(1.03); box-shadow: 0 4px 20px rgba(var(--shadow-rgb),0.4); animation-play-state: paused; } #aeo-popup-root .banner-cta .arrow { font-size: 16px; line-height: 1; transition: transform .2s; } #aeo-popup-root .banner-cta:hover .arrow { transform: translateX(3px); } /* ── IFRAME MODAL (full-screen takeover) ────────────────────────── */ /* Matches the Verdict V2 full-page lead capture pattern: edge-to-edge shell, no card chrome, just a translucent floating top bar with "Back to article" and a close pill. The AEO funnel's own branding inside the iframe carries the visual weight. */ #aeo-popup-root .aeo-modal { position: fixed; inset: 0; z-index: 10000; background: #ffffff; display: flex; flex-direction: column; opacity: 0; pointer-events: none; transition: opacity .25s ease; } #aeo-popup-root .aeo-modal.open { opacity: 1; pointer-events: all; } #aeo-popup-root .aeo-modal-backdrop { display: none; } #aeo-popup-root .aeo-modal-shell { position: relative; z-index: 1; display: flex; flex-direction: column; width: 100%; height: 100%; background: #ffffff; } #aeo-popup-root .aeo-modal-bar { position: relative; z-index: 3; display: flex; align-items: center; justify-content: space-between; padding: 12px 20px; background: #ffffff; border-bottom: 1px solid rgba(0,0,0,0.06); flex-shrink: 0; } #aeo-popup-root .aeo-modal-back { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-body); font-size: 13px; font-weight: 500; color: var(--ink-soft); background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 8px; transition: background .15s, color .15s; } #aeo-popup-root .aeo-modal-back:hover { background: #F0F1EC; color: var(--ink); } #aeo-popup-root .aeo-modal-iframe-wrap { position: relative; flex: 1; background: #ffffff; overflow: hidden; } #aeo-popup-root .aeo-modal-iframe { width: 100%; height: 100%; border: 0; display: block; background: #ffffff; } #aeo-popup-root .aeo-modal-loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); background: #ffffff; transition: opacity .3s ease; z-index: 1; pointer-events: none; } #aeo-popup-root .aeo-modal-iframe-wrap.loaded .aeo-modal-loading { opacity: 0; } #aeo-popup-root .aeo-modal-loading .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); animation: aeoPulse 1.2s ease-in-out infinite; margin-right: 8px; } /* lock background scroll when modal is open */ body.aeo-modal-open { overflow: hidden; } /* Bar collapses to headline + CTA on narrower viewports, but the card keeps its 340px bottom-left footprint all the way down to phone widths. Real phones (≤480px) get the full-width card so the CTA stays tappable. */ @media (max-width: 900px) { #aeo-popup-root .banner-inner { padding: 0 16px; gap: 12px; } #aeo-popup-root .banner-label, #aeo-popup-root .banner-divider-v, #aeo-popup-root .banner-sub { display: none; } #aeo-popup-root .banner-headline { font-size: 13px; } #aeo-popup-root .banner-cta { font-size: 13px; padding: 9px 18px; } } @media (max-width: 480px) { #aeo-popup-root .sticky-card { left: 12px; bottom: 12px; width: calc(100vw - 24px); } } @media (prefers-reduced-motion: reduce) { #aeo-popup-root .sticky-card, #aeo-popup-root .sticky-banner.visible, #aeo-popup-root .sc-cta, #aeo-popup-root .banner-cta { animation: none !important; } #aeo-popup-root.aeo-iframe-ready .sticky-card { transform: none; opacity: 1; } } </style> <div id="aeo-popup-root" data-variant="small-report" data-domain="rankanddiscover.com"> <div class="sticky-card" id="aeoStickyCard" role="complementary" aria-label="AI Visibility Radar — Free AEO Report"> <div class="sc-inner"> <div class="sc-header"> <span class="sc-label"><span class="sc-dot"></span>AI VISIBILITY RADAR</span> <button type="button" class="sc-close" id="aeoCardClose" aria-label="Dismiss">×</button> </div> <p class="sc-headline">Are AI engines recommending your brand?</p> <p class="sc-sub">Check your score on 5 AI engines — instantly.</p> <div class="sc-ticker-wrap"><div class="sc-ticker" id="aeoScTicker"></div></div> <a href="#" class="sc-cta" id="aeoCardCta"> Check for Free <span class="arrow">→</span> </a> </div> </div> <div class="sticky-banner" id="aeoStickyBanner" role="complementary" aria-label="AI Visibility Radar — Free AEO Report"> <div class="banner-inner"> <span class="banner-label">AI VISIBILITY RADAR</span> <div class="banner-divider-v"></div> <p class="banner-headline">Are AI engines recommending your brand?</p> <span class="banner-sub">Check your score on 5 AI engines — instantly.</span> <a href="#" class="banner-cta" id="aeoBarCta"> Check for Free <span class="arrow">→</span> </a> </div> </div> <div class="aeo-modal" id="aeoModal" role="dialog" aria-modal="true" aria-label="AI Visibility Radar — Free AEO Report" aria-hidden="true"> <div class="aeo-modal-backdrop" data-aeo-close></div> <div class="aeo-modal-shell"> <header class="aeo-modal-bar"> <button type="button" class="aeo-modal-back" data-aeo-close> <span aria-hidden="true">←</span> Back to article </button> </header> <div class="aeo-modal-iframe-wrap" id="aeoModalIframeWrap"> <div class="aeo-modal-loading"><span class="dot"></span>Loading report…</div> <iframe id="aeoModalIframe" class="aeo-modal-iframe" title="AI Visibility Radar — Free AEO Report" referrerpolicy="no-referrer-when-downgrade" allow="clipboard-write" src="https://aeo.prod-mobtools.com/aeo/small-report?embed=1&utm_source=rankanddiscover.com&utm_medium=satellite&utm_campaign=aeo-popup&utm_content=small-report"></iframe> </div> </div> </div> </div> <script id="aeo-popup-script"> (function () { var root = document.getElementById('aeo-popup-root'); if (!root) return; var card = document.getElementById('aeoStickyCard'); var bar = document.getElementById('aeoStickyBanner'); var modal = document.getElementById('aeoModal'); var iframe = document.getElementById('aeoModalIframe'); var wrap = document.getElementById('aeoModalIframeWrap'); var closeBtn = document.getElementById('aeoCardClose'); var cardCta = document.getElementById('aeoCardCta'); var barCta = document.getElementById('aeoBarCta'); var ticker = document.getElementById('aeoScTicker'); /* ---------- analytics -------------------------------- Posts to the existing /wp-json/satellite/v1/lead-event proxy, which forwards to the backend's POST /api/leads/event. Events here are prefixed with "aeo_" so the lawyer funnel chart on the same dashboard never picks them up. ----------------------------------------------------- */ var AEO_DOMAIN = "rankanddiscover.com"; var AEO_VARIANT = "small-report"; var AEO_NICHE = "marketing"; var AEO_EVENT_URL = "https:\/\/rankanddiscover.com\/wp-json\/satellite\/v1\/lead-event"; var AEO_EVENT_NONCE = "1adc5304df"; /* localStorage visitor_id so unique-clicker counts on the dashboard are stable across sessions on the same browser. UUIDv4-ish via random bytes; no PII, just a stable handle for COUNT(DISTINCT) on the backend. */ function aeoGetVisitorId() { try { var KEY = 'aeo_vid'; var existing = localStorage.getItem(KEY); if (existing) return existing; var b = (crypto && crypto.getRandomValues) ? crypto.getRandomValues(new Uint8Array(16)) : (function () { var arr = []; for (var i=0;i<16;i++) arr.push(Math.floor(Math.random()*256)); return arr; })(); b[6] = (b[6] & 0x0f) | 0x40; // version 4 b[8] = (b[8] & 0x3f) | 0x80; // variant var hex = Array.prototype.map.call(b, function (x) { return ('0' + x.toString(16)).slice(-2); }).join(''); var id = hex.slice(0,8)+'-'+hex.slice(8,12)+'-'+hex.slice(12,16)+'-'+hex.slice(16,20)+'-'+hex.slice(20,32); localStorage.setItem(KEY, id); return id; } catch (e) { return ''; // private mode / disabled storage -- silently drop } } var AEO_VISITOR_ID = aeoGetVisitorId(); function aeoTrack(eventType, extraMeta) { try { var meta = { variant: AEO_VARIANT, niche: AEO_NICHE }; if (extraMeta) for (var k in extraMeta) if (Object.prototype.hasOwnProperty.call(extraMeta, k)) meta[k] = extraMeta[k]; var payload = { domain: AEO_DOMAIN, event_type: eventType, visitor_id: AEO_VISITOR_ID, page_url: location.href, metadata_json: JSON.stringify(meta) }; var body = JSON.stringify(payload); if (navigator.sendBeacon) { navigator.sendBeacon( AEO_EVENT_URL + '?_wpnonce=' + encodeURIComponent(AEO_EVENT_NONCE), new Blob([body], { type: 'application/json' }) ); } else { fetch(AEO_EVENT_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': AEO_EVENT_NONCE }, body: body, keepalive: true }); } } catch (e) { /* analytics must never break the popup */ } } /* ---------- cookies ---------- */ function readCookie(name) { var m = document.cookie.match('(?:^|;)\\s*' + name + '=([^;]*)'); return m ? decodeURIComponent(m[1]) : ''; } function writeCookie(name, value, days) { var d = new Date(); d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000); document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + d.toUTCString() + '; path=/; SameSite=Lax'; } /* Cookie names are versioned. An earlier iteration of this script set aeo_lead_done from a 15s dwell-time heuristic (since removed); any tester who left the modal open during that period now carries a 30-day cookie that silently hides the popup forever. Bumping the name to _v2 retires that stale state without forcing anyone to clear browser cookies. */ var CARD_DISMISSED = 'aeo_card_dismissed_v2'; var LEAD_DONE = 'aeo_lead_done_v2'; if (readCookie(LEAD_DONE) === '1') { root.classList.add('aeo-lead-done'); return; } /* ---------- reveal the card (or bar) ---------- The iframe is preloading in the background regardless of card state, so we don't gate reveal on it -- we just slide the card up on a quick fixed timer so the popup is visible reliably on every refresh, even when the cross-origin iframe's load event is slow or never fires. By the time the user finishes reading the article and clicks the CTA, the iframe is virtually always fully loaded, so clicks still open the modal instantly. */ var revealed = false; var dismissedBefore = readCookie(CARD_DISMISSED) === '1'; if (dismissedBefore) root.classList.add('aeo-skip-card'); function reveal() { if (revealed) return; revealed = true; if (dismissedBefore) { if (bar) bar.classList.add('visible'); aeoTrack('aeo_bar_impression', { source: 'bar' }); } else { root.classList.add('aeo-iframe-ready'); aeoTrack('aeo_impression', { source: 'card' }); } } /* 600ms is long enough to feel intentional (not jarring on first paint), short enough that it always wins against a slow cross-origin iframe. */ setTimeout(reveal, 600); /* ---------- ticker ---------- Three full copies of the chip list, not two. The aeoScTicker keyframe translates by exactly one copy's width (-33.3333%) so the second copy slides into the first's position seamlessly; the third copy is there to keep the right edge of the card filled while the second is doing the heavy lifting -- one copy alone (216px) is narrower than the visible card content area, so a doubled ticker leaves a visible gap at the right edge near the end of every animation cycle. */ var TOOLS = [{"name":"Gemini","bg":"#1A73E8","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/gemini.svg"},{"name":"Grok","bg":"#111111","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/grok.svg"},{"name":"Perplexity","bg":"#1FB8CD","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/perplexity.svg"},{"name":"ChatGPT","bg":"#10A37F","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/chatgpt.svg"},{"name":"Copilot","bg":"#FFFFFF","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/copilot.svg"},{"name":"Claude","bg":"#D97757","logo":"https:\/\/rankanddiscover.com\/wp-content\/mu-plugins\/aeo-assets\/logos\/claude.svg"}]; if (ticker) { var tripled = TOOLS.concat(TOOLS).concat(TOOLS); ticker.innerHTML = tripled.map(function (t) { return '<div class="sc-logo-chip" title="' + t.name + '" style="background:' + t.bg + ';">' + '<img src="' + t.logo + '" alt="' + t.name + '" loading="lazy" width="18" height="18">' + '</div>'; }).join(''); } /* ---------- card -> bar dismissal ---------- The slide-down animation is 0.4s. We use a matched setTimeout instead of animationend because Chrome occasionally swallows the event when another animation (the breathing background) is in flight on the same element. */ if (closeBtn) { closeBtn.addEventListener('click', function () { writeCookie(CARD_DISMISSED, '1', 30); aeoTrack('aeo_card_dismiss', { source: 'card' }); card.classList.add('hiding'); setTimeout(function () { card.style.display = 'none'; if (bar) bar.classList.add('visible'); }, 420); }); } /* ---------- modal open / close ---------- */ if (iframe && wrap) { if (iframe.complete) wrap.classList.add('loaded'); else iframe.addEventListener('load', function () { wrap.classList.add('loaded'); }, { once: true }); } function swapCardToBar() { if (!card || card.style.display === 'none' || card.classList.contains('hiding')) return; card.classList.add('hiding'); setTimeout(function () { card.style.display = 'none'; if (bar) bar.classList.add('visible'); }, 420); } function openModal(e) { if (e) e.preventDefault(); if (!modal) return; modal.setAttribute('aria-hidden', 'false'); requestAnimationFrame(function () { modal.classList.add('open'); }); document.body.classList.add('aeo-modal-open'); } function closeModal() { if (!modal || !modal.classList.contains('open')) return; modal.classList.remove('open'); document.body.classList.remove('aeo-modal-open'); setTimeout(function () { modal.setAttribute('aria-hidden', 'true'); }, 320); aeoTrack('aeo_modal_close'); /* If the card was still showing behind the modal, collapse it to the bar so the user has an obvious re-entry point. No cookie is set here -- only the explicit X on the card persists dismissal across page loads. */ swapCardToBar(); } if (cardCta) cardCta.addEventListener('click', function (e) { aeoTrack('aeo_cta_click', { source: 'card' }); openModal(e); }); if (barCta) barCta.addEventListener('click', function (e) { aeoTrack('aeo_cta_click', { source: 'bar' }); openModal(e); }); /* Generic trigger: any element with [data-aeo-open] opens the same modal. The in-article banner (aeo-inline-banner.php) uses this so it doesn't have to duplicate the modal HTML/JS -- it just renders a CTA with data-aeo-open + data-aeo-source="inline" and rides on the popup infrastructure that's already in the footer. Source is read from data-aeo-source so we can split CTR by surface in the analytics dashboard (card / bar / inline / future surfaces). */ document.querySelectorAll('[data-aeo-open]').forEach(function (el) { el.addEventListener('click', function (e) { var source = el.getAttribute('data-aeo-source') || 'external'; aeoTrack('aeo_cta_click', { source: source }); openModal(e); }); }); if (modal) { modal.querySelectorAll('[data-aeo-close]').forEach(function (el) { el.addEventListener('click', closeModal); }); } document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && modal && modal.classList.contains('open')) closeModal(); }); /* ---------- future postMessage handshake (stub) ---------- Listens for a "lead-complete" event from the iframe so we can flip the LEAD_DONE cookie immediately on real submission (not on dwell time). Wire this up on the AEO side and remove the dwell-time fallback above. */ window.addEventListener('message', function (e) { if (!e || !e.origin || e.origin.indexOf('aeo.prod-mobtools.com') === -1) return; var data = e.data || {}; if (data && data.type === 'aeo:lead-complete') { writeCookie(LEAD_DONE, '1', 30); root.classList.add('aeo-lead-done'); closeModal(); } }); })(); </script> <script id="satellite-cta-fallback">(function(){ function ready(fn){ if(document.readyState!=='loading'){fn();} else {document.addEventListener('DOMContentLoaded',fn);} } ready(function(){ document.querySelectorAll('[class*="-sticky-cta"]').forEach(function(el){ var b = el.querySelector('[class*="-sticky-cta-btn"]'); if (b && /subscribe/i.test(b.textContent)) { el.remove(); } }); }); document.addEventListener('satellite:open-lead-popup', function(){ var has = (window.LawyerLeadFormV2&&window.LawyerLeadFormV2.open)||(window.AeoLeadPopup&&window.AeoLeadPopup.open)||(window.ExitIntentPopup&&window.ExitIntentPopup.open); if (!has) { window.location.href = 'https://rankanddiscover.com/contact/'; } }); })();</script> <script> (function(){ var bar = document.getElementById('reading-progress'); if(!bar) return; var article = document.querySelector('.post-content'); if(!article) return; var milestones = {25:false,50:false,75:false,100:false}; var startTime = Date.now(); function sendGA4(name, params) { if (window.gtag) window.gtag('event', name, params); } window.addEventListener('scroll', function(){ var rect = article.getBoundingClientRect(); var total = article.offsetHeight - window.innerHeight; var progress = Math.min(100, Math.max(0, (-rect.top / total) * 100)); bar.style.width = progress + '%'; var pct = Math.floor(progress); [25,50,75,100].forEach(function(m){ if (pct >= m && !milestones[m]) { milestones[m] = true; sendGA4('scroll_depth', {percent: m, reading_seconds: Math.round((Date.now()-startTime)/1000)}); } }); }, {passive:true}); function sendReadingTime() { var seconds = Math.round((Date.now()-startTime)/1000); if (seconds > 3) sendGA4('reading_time', {seconds: seconds, scroll_reached: Math.max.apply(null, Object.keys(milestones).filter(function(k){return milestones[k];})) || 0}); } document.addEventListener('visibilitychange', function(){ if(document.visibilityState==='hidden') sendReadingTime(); }); window.addEventListener('beforeunload', sendReadingTime); })(); </script> <script> (function(){ var toc = document.querySelector('.toc-container'); if(!toc) return; var title = toc.querySelector('.toc-title'); if(window.innerWidth <= 768) { toc.classList.add('toc-collapsed'); title.addEventListener('click', function(){ toc.classList.toggle('toc-collapsed'); }); } var links = toc.querySelectorAll('.toc-list a'); var sections = []; links.forEach(function(a){ var id = a.getAttribute('href'); if(id) { var el = document.querySelector(id); if(el) sections.push({el:el,link:a}); } }); if(!sections.length) return; var raf; window.addEventListener('scroll', function(){ if(raf) return; raf = requestAnimationFrame(function(){ raf = null; var scrollY = window.scrollY + 120; var active = sections[0]; for(var i=0;i<sections.length;i++){ if(sections[i].el.offsetTop <= scrollY) active = sections[i]; } links.forEach(function(l){ l.classList.remove('toc-active'); }); if(active) active.link.classList.add('toc-active'); }); }, {passive:true}); })(); </script> </body> </html>