1<!DOCTYPE html><html lang="en"> <head><!-- Global --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="icon" href="/favicon.ico" sizes="32x32"><link rel="apple-touch-icon" href="/apple-touch-icon.png"><link rel="manifest" href="/site.webmanifest"><!-- Preload self hosted text face (all UI and prose). The italic file is 2 not preloaded: it only serves emphasised prose and can arrive late. --><link rel="preload" href="/fonts/instrument-sans-latin-wght-normal.woff2" as="font" type="font/woff2" crossorigin><link rel="sitemap" href="/sitemap-index.xml"><link rel="ai-catalog" href="/.well-known/ai-catalog.json"><link rel="alternate" type="application/rss+xml" title="Suganthan Mohanadasan" href="https://suganthan.com/rss.xml"><meta name="generator" content="Astro v5.17.3"><!-- Canonical --><link rel="canonical" href="https://suganthan.com/blog/"><!-- Robots. max-image-preview:large is required for Google Discover 3 eligibility on image display (per Google's official Discover docs). 4 Without it, Discover shows posts as text-only cards instead of the 5 large-image format that gets meaningful CTR. --><meta name="robots" content="index, follow, max-image-preview:large"><!-- Primary --><title>Blog â Suganthan</title><meta name="title" content="Blog â Suganthan"><meta name="description" content="Articles on SEO, search journey optimisation, AI tools, content strategy, and technical search by Suganthan Mohanadasan."><meta name="author" content="Suganthan Mohanadasan"><!-- Open Graph --><meta property="og:type" content="website"><meta property="og:url" content="https://suganthan.com/blog/"><meta property="og:title" content="Blog â Suganthan"><meta property="og:description" content="Articles on SEO, search journey optimisation, AI tools, content strategy, and technical search by Suganthan Mohanadasan."><meta property="og:image" content="https://suganthan.com/og-default.png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="og:image:type" content="image/png"><meta property="og:image:alt" content="Blog â Suganthan"><meta property="og:site_name" content="Suganthan Mohanadasan"><meta property="og:locale" content="en_US"><!-- Twitter --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@suganthan"><meta name="twitter:creator" content="@suganthan"><meta name="twitter:title" content="Blog â Suganthan"><meta name="twitter:description" content="Articles on SEO, search journey optimisation, AI tools, content strategy, and technical search by Suganthan Mohanadasan."><meta name="twitter:image" content="https://suganthan.com/og-default.png"><meta name="twitter:image:alt" content="Blog â Suganthan"><!-- Article dates (for blog posts) -->
5<script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{"token": "658f4920d8c848578c47696234718a35"}"></script>
5<script src="https://tracking.suganthan.com/api/script.js" data-site-id="159421108300" defer></script>
5<meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback" content="swap">
5<script type="module" src="/_astro/ClientRouter.astro_astro_type_script_index_0_lang.BFfqj1ee.js"></script>
5<script> 6 // Runs before first paint. Sets the theme selector, and for dark mode also 7 // stamps the dark tokens inline on <html> until the stylesheet has loaded: 8 // Safari painted invisible links in dark mode when var() rules still held 9 // the light :root values during first paint (fix kept from the 2026-08-29 10 // layout). The inline values are removed on DOMContentLoaded, by which time 11 // the render blocking stylesheet owns every token, so nothing can drift. 12 (() => { 13 let stored; 14 try { stored = localStorage.getItem('theme'); } catch {} 15 const theme = stored === 'dark' || stored === 'light' 16 ? stored : (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); 17 const d = document.documentElement; 18 d.dataset.theme = theme; 19 if (theme === 'dark') { 20 const dark = { 21 '--color-bg': '25, 29, 35', 22 '--color-text': '226, 229, 232', 23 '--color-text-secondary': '169, 174, 182', 24 '--color-border': '47, 51, 56', 25 '--color-code-bg': '38, 42, 48', 26 '--color-code-block-bg': '35, 39, 44', 27 '--color-accent': '126, 167, 220',
28 '--bg': 'oklch(23% 0.012 255)', 29 '--ink': 'oklch(92% 0.005 250)', 30 '--border': 'oklch(32% 0.01 255)', 31 '--accent': 'oklch(72% 0.09 255)', 32 }; 33 d.style.backgroundColor = 'rgb(25,29,35)'; 34 d.style.color = 'rgb(226,229,232)'; 35 for (const key in dark) d.style.setProperty(key, dark[key]); 36 document.addEventListener('DOMContentLoaded', () => { 37 d.style.backgroundColor = ''; 38 d.style.color = ''; 39 for (const key in dark) d.style.removeProperty(key); 40 }, { once: true }); 41 } 42 })(); 43</script>
43<link rel="stylesheet" href="/_astro/_slug_.pfV2LWus.css"> 44<style>.featured-story[data-astro-cid-3av72bsu]{display:grid;grid-template-columns:minmax(0,1fr) 256px;align-items:start;gap:28px}.featured-story-no-image[data-astro-cid-3av72bsu]{grid-template-columns:minmax(0,1fr)}.featured-content[data-astro-cid-3av72bsu]{min-width:0;grid-column:1;grid-row:1}.featured-media[data-astro-cid-3av72bsu]{display:block;grid-column:2;grid-row:1;border-radius:4px}.featured-image[data-astro-cid-3av72bsu]{display:block;width:100%;height:auto;aspect-ratio:4 / 3;object-fit:cover;border-radius:4px}.featured-title-link[data-astro-cid-3av72bsu]{text-decoration:none}.featured-title[data-astro-cid-3av72bsu]{margin:0 0 12px;color:var(--ink);font-size:25px;font-weight:650;line-height:1.27;letter-spacing:-.02em;overflow-wrap:anywhere;text-wrap:pretty;transition:color .15s ease}.featured-title-link[data-astro-cid-3av72bsu]:visited .featured-title[data-astro-cid-3av72bsu]{color:var(--desc-ink)}.featured-title-link[data-astro-cid-3av72bsu]:hover .featured-title[data-astro-cid-3av72bsu]{color:var(--accent)}.featured-description[data-astro-cid-3av72bsu]{margin:0 0 14px;font-size:14.5px;line-height:1.55;color:var(--desc-ink)}.featured-meta[data-astro-cid-3av72bsu]{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;color:var(--muted-ink);font-size:13px;line-height:1.5}.featured-read[data-astro-cid-3av72bsu]{display:inline-flex;align-items:center;gap:6px;min-height:44px;margin-top:3px;color:var(--accent);font-size:14px;font-weight:550;text-decoration:none}.featured-read[data-astro-cid-3av72bsu]:hover{text-decoration:underline;text-underline-offset:4px}.featured-title-link[data-astro-cid-3av72bsu]:focus-visible,.featured-read[data-astro-cid-3av72bsu]:focus-visible{outline:2px solid var(--accent);outline-offset:5px}@media(max-width:640px){.featured-story[data-astro-cid-3av72bsu]{display:flow-root}.featured-media[data-astro-cid-3av72bsu]{float:right;width:112px;margin:2px 0 12px 18px}.featured-title[data-astro-cid-3av72bsu]{font-size:22px;line-height:1.28;margin-bottom:12px}.featured-description[data-astro-cid-3av72bsu]{clear:both;font-size:14px}.featured-meta[data-astro-cid-3av72bsu]{clear:both}}@media(prefers-reduced-motion:reduce){.featured-title[data-astro-cid-3av72bsu]{transition:none}} 45</style> 46<link rel="stylesheet" href="/_astro/index.iZolKxLp.css">
46<script type="module" src="/_astro/page.IvKoM_B8.js"></script>
46</head> <body> <a href="#main" class="skip-link">Skip to content</a> <header class="site-header" data-astro-cid-3ef6ksr2> <nav class="primary-nav" aria-label="Main navigation" data-astro-cid-3ef6ksr2> <a href="/" class="wordmark" data-astro-cid-3ef6ksr2>Suganthan<sup class="logo-tm" title="SUGANTHAN is a UK registered trade mark (UK00004354704)" data-astro-cid-3ef6ksr2>®</sup></a> <div class="nav-actions" data-astro-cid-3ef6ksr2> <div class="desktop-links" data-astro-cid-3ef6ksr2> <a href="/ai-seo/" class="nav-link" data-astro-cid-3ef6ksr2>AI SEO</a><a href="/ai-seo-research/" class="nav-link" data-astro-cid-3ef6ksr2>Research</a><details class="writing-menu" data-astro-cid-3ef6ksr2> <summary class="nav-link is-active" data-astro-cid-3ef6ksr2> 47Writing 48<svg width="12" height="12" viewBox="0 0 20 20" fill="none" aria-hidden="true" data-astro-cid-3ef6ksr2><path d="m5 7.5 5 5 5-5" stroke="currentColor" stroke-width="1.5" data-astro-cid-3ef6ksr2></path></svg> </summary> <div class="writing-options" data-astro-cid-3ef6ksr2> <a href="/blog/" aria-current="page" data-astro-cid-3ef6ksr2><span data-astro-cid-3ef6ksr2>Articles</span><small data-astro-cid-3ef6ksr2>Research and longer reads</small></a><a href="/notes/" data-astro-cid-3ef6ksr2><span data-astro-cid-3ef6ksr2>Notes</span><small data-astro-cid-3ef6ksr2>Short takes and observations</small></a><a href="/newsletter/" data-astro-cid-3ef6ksr2><span data-astro-cid-3ef6ksr2>Newsletter</span><small data-astro-cid-3ef6ksr2>New writing in your inbox</small></a> </div> </details><a href="/free-seo-tools/" class="nav-link" data-astro-cid-3ef6ksr2>Tools</a><a href="/about/" class="nav-link" data-astro-cid-3ef6ksr2>About</a> <a href="/work-with-me/" class="nav-cta" data-conversion-link="header" data-agency-placement="header" data-agency-topic="general" data-astro-cid-3ef6ksr2>Work with Snippet</a> </div> <button id="theme-toggle" class="theme-toggle" aria-label="Dark mode" aria-pressed="false" type="button" data-astro-cid-x3pjskd3> <!-- Sun icon (Lucide) â shown when dark mode is active (click to go light) --> <svg id="sun-icon" class="w-[16px] h-[16px] hidden" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-x3pjskd3> <circle cx="12" cy="12" r="4" data-astro-cid-x3pjskd3></circle> <path d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" data-astro-cid-x3pjskd3></path> </svg> <!-- Moon icon (Lucide) â shown when light mode is active (click to go dark) --> <svg id="moon-icon" class="w-[16px] h-[16px] hidden" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" data-astro-cid-x3pjskd3> <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" data-astro-cid-x3pjskd3></path> </svg> </button>
48<script type="module">const d=matchMedia("(prefers-color-scheme: dark)");function a(){let e;try{e=localStorage.getItem("theme")}catch{}return e==="dark"||e==="light"?e:d.matches?"dark":"light"}function t(e=a()){document.documentElement.dataset.theme=e,document.getElementById("sun-icon")?.classList.toggle("hidden",e!=="dark"),document.getElementById("moon-icon")?.classList.toggle("hidden",e!=="light"),document.getElementById("theme-toggle")?.setAttribute("aria-pressed",String(e==="dark"))}function o(){t();const e=document.getElementById("theme-toggle");!e||e.dataset.bound||(e.dataset.bound="true",e.addEventListener("click",()=>{const n=document.documentElement.dataset.theme==="dark"?"light":"dark";try{localStorage.setItem("theme",n)}catch{}t(n)}))}o();d.addEventListener("change",()=>t());document.addEventListener("astro:before-swap",e=>{e.newDocument.documentElement.dataset.theme=document.documentElement.dataset.theme||a()});document.addEventListener("astro:page-load",o);</script>
48 <button id="menu-toggle" type="button" aria-label="Open menu" aria-expanded="false" aria-controls="mobile-menu" data-astro-cid-3ef6ksr2> <svg class="menu-open-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true" data-astro-cid-3ef6ksr2><path d="M4 6h16M4 12h16M4 18h16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" data-astro-cid-3ef6ksr2></path></svg> <svg class="menu-close-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true" data-astro-cid-3ef6ksr2><path d="m6 6 12 12M18 6 6 18" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" data-astro-cid-3ef6ksr2></path></svg> </button> </div> </nav> <nav id="mobile-menu" aria-label="Mobile navigation" hidden data-astro-cid-3ef6ksr2> <a href="/ai-seo/" data-astro-cid-3ef6ksr2>AI SEO</a> <a href="/ai-seo-research/" data-astro-cid-3ef6ksr2>Research</a> <div class="mobile-writing" role="group" aria-labelledby="mobile-writing-label" data-astro-cid-3ef6ksr2> <span class="mobile-group-label" id="mobile-writing-label" data-astro-cid-3ef6ksr2>Writing</span> <a href="/blog/" aria-current="page" data-astro-cid-3ef6ksr2>Articles</a> <a href="/notes/" data-astro-cid-3ef6ksr2>Notes</a> <a href="/newsletter/" data-astro-cid-3ef6ksr2>Newsletter</a> </div> <a href="/free-seo-tools/" data-astro-cid-3ef6ksr2>Tools</a> <a href="/about/" data-astro-cid-3ef6ksr2>About</a> <a href="/work-with-me/" class="nav-cta" data-conversion-link="mobile-menu" data-agency-placement="mobile-menu" data-agency-topic="general" data-astro-cid-3ef6ksr2>Work with Snippet</a> </nav> </header>
48<script type="module">function i(){const t=document.querySelector(".site-header");if(!t||t.dataset.bound)return;t.dataset.bound="true";const n=t.querySelector("#menu-toggle"),a=t.querySelector("#mobile-menu"),o=t.querySelector(".writing-menu");if(!n||!a)return;const r=(e=!1)=>{const s=!a.hidden||!!o?.open;a.hidden=!0,n.setAttribute("aria-expanded","false"),n.setAttribute("aria-label","Open menu"),o&&(o.open=!1),e&&s&&(matchMedia("(max-width:959px)").matches?n:o?.querySelector("summary"))?.focus()};n.addEventListener("click",()=>{const e=a.hidden;a.hidden=!e,n.setAttribute("aria-expanded",String(e)),n.setAttribute("aria-label",e?"Close menu":"Open menu")}),t.addEventListener("keydown",e=>{e.key==="Escape"&&r(!0)}),t.addEventListener("focusout",e=>{e.relatedTarget instanceof Node&&!t.contains(e.relatedTarget)&&r()});const d=e=>{e.target instanceof Node&&!t.contains(e.target)&&r()};document.addEventListener("pointerdown",d),document.addEventListener("astro:before-swap",()=>document.removeEventListener("pointerdown",d),{once:!0})}i();document.addEventListener("astro:page-load",i);</script>
48 <main id="main" tabindex="-1" class="flex-1 px-4 sm:px-6 py-10 sm:py-16"> <div class="max-w-[var(--max-width-content)] mx-auto" data-astro-cid-5tznm7mj> <div class="flex items-baseline gap-3 flex-wrap" data-astro-cid-5tznm7mj> <h1 class="mb-0" data-astro-cid-5tznm7mj>Blog</h1> <span id="post-count" class="inline-note" role="status" aria-live="polite" aria-atomic="true" data-astro-cid-5tznm7mj>51 posts</span> </div> <div class="archive-controls" data-astro-cid-5tznm7mj> <div class="archive-topics" role="group" aria-label="Filter posts by topic" data-astro-cid-5tznm7mj> <button type="button" class="chip-active topic-chip" data-topic="all" aria-pressed="true" data-astro-cid-5tznm7mj>All</button> <button type="button" class="topic-chip" data-topic="ai-seo" aria-pressed="false" data-astro-cid-5tznm7mj>AI SEO & GEO</button><button type="button" class="topic-chip" data-topic="technical-seo" aria-pressed="false" data-astro-cid-5tznm7mj>Technical SEO</button><button type="button" class="topic-chip" data-topic="strategy" aria-pressed="false" data-astro-cid-5tznm7mj>Strategy</button><button type="button" class="topic-chip" data-topic="tools" aria-pressed="false" data-astro-cid-5tznm7mj>Tools & MCP</button><button type="button" class="topic-chip" data-topic="other" aria-pressed="false" data-astro-cid-5tznm7mj>Everything else</button> </div> <div class="archive-search" data-astro-cid-5tznm7mj> <label for="post-search" data-astro-cid-5tznm7mj>Search posts</label> <input id="post-search" type="search" placeholder="Search by title or descriptionâ¦" autocomplete="off" aria-label="Search posts" class="form-input" data-astro-cid-5tznm7mj> </div> </div> <!-- Featured latest --> <section id="featured-post" data-post-entry data-topics="tools" data-search="Your Google Search Console queries need context A free tool that sorts a Google Search Console query export against a short business brief, how Jev labels each query, and what to do with the queries it rejects." data-astro-cid-5tznm7mj> <div class="section-head !mb-3" data-astro-cid-5tznm7mj> <h2 class="!mt-0" data-astro-cid-5tznm7mj>Latest</h2> </div> <article class="featured-story" data-astro-cid-3av72bsu> <a href="/blog/keyword-relevance-filter/" class="featured-media" aria-hidden="true" tabindex="-1" data-astro-cid-3av72bsu> <img src="/_astro/heroImage.c5Jtv0py_ZvF2VD.webp" srcset="/_astro/heroImage.c5Jtv0py_yBgUU.webp 240w, /_astro/heroImage.c5Jtv0py_Z2qsaNh.webp 512w, /_astro/heroImage.c5Jtv0py_B8aIK.webp 768w" alt sizes="(max-width: 640px) 112px, 256px" data-astro-cid-3av72bsu="true" loading="lazy" decoding="async" fetchpriority="auto" width="2258" height="2238" class="featured-image"> </a> <div class="featured-content" data-astro-cid-3av72bsu> <a href="/blog/keyword-relevance-filter/" class="featured-title-link" data-astro-cid-3av72bsu> <h3 class="featured-title" data-astro-cid-3av72bsu="true">Your Google Search Console queries need context</h3> </a> <p class="featured-description" data-astro-cid-3av72bsu>A free tool that sorts a Google Search Console query export against a short business brief, how Jev labels each query, and what to do with the queries it rejects.</p> <div class="featured-meta" data-astro-cid-3av72bsu> <time datetime="2026-09-23T00:00:00.000Z"> 23rd September 2026 </time> <span aria-hidden="true" data-astro-cid-3av72bsu>·</span><span data-astro-cid-3av72bsu>Quick setup</span> </div> <a href="/blog/keyword-relevance-filter/" class="featured-read" aria-label="Read Your Google Search Console queries need context" data-astro-cid-3av72bsu>Read article <span aria-hidden="true" data-astro-cid-3av72bsu>→</span></a> </div> </article> </section> <!-- Every article remains in the source; filters control visibility. --> <div id="post-grid" class="archive-list" data-astro-cid-5tznm7mj> <article class="post-card archive-row" data-post-entry data-topics="ai-seo tools" data-search="i made my website charge ai agents a penny per page. then i watched claude pay it. google is testing paying publishers when their pages feed its ai answers, on terms only google can see. my site runs the other version over x402. it returns http 402 to ai agents and unlocks for a cent in usdc, with a public re
48ceipt for every crawl, which is the loop those cloudflare wallet handles will run." data-astro-cid-5tznm7mj> <a href="/blog/x402-pay-per-crawl/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.cMhCdLQ6_WvOej.webp" srcset="/_astro/heroImage.cMhCdLQ6_2ml67o.webp 160w, /_astro/heroImage.cMhCdLQ6_1qn0Bd.webp 224w, /_astro/heroImage.cMhCdLQ6_Z2apL7g.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1376" height="768" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/x402-pay-per-crawl/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I made my website charge AI agents a penny per page. Then I watched Claude pay it.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Google is testing paying publishers when their pages feed its AI answers, on terms only Google can see. My site runs the other version over x402. It returns HTTP 402 to AI agents and unlocks for a cent in USDC, with a public receipt for every crawl, which is the loop those Cloudflare wallet handles will run.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-09-15T00:00:00.000Z"> 15th September 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="one page earned 102,657 image impressions and 2 clicks. i shipped 8 free tools that find pages like it. image search on one client site ran at 64% of web's impressions and 11% of its clicks, and no tool in the stack could see it. the new gsc mcp update ships 8 free image seo tools that read that surface and audit the pages behind it." data-astro-cid-5tznm7mj> <a href="/blog/gsc-mcp-image-seo-tools/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.pEljSCPy_3XQpv.webp" srcset="/_astro/heroImage.pEljSCPy_ZvzSis.webp 160w, /_astro/heroImage.pEljSCPy_Tvr8g.webp 224w, /_astro/heroImage.pEljSCPy_Z10GPv7.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1792" height="1008" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/gsc-mcp-image-seo-tools/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>One Page Earned 102,657 Image Impressions and 2 Clicks. I Shipped 8 Free Tools That Find Pages Like It.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Image search on one client site ran at 64% of web's impressions and 11% of its clicks, and no tool in the stack could see it. The new GSC MCP update ships 8 free image SEO tools that read that surface and audit the pages behind it.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-27T00:00:00.000Z"> 27th August 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo" data-search="chatgpt searches individual subreddits by name a capture this week has chatgpt targeting one subreddit directly, with a ten-year window, on a query where bing returns no reddit at all. reddit was 48 of the 71 pages it fetched and won 6 of the 8 citations. four days earlier, a different query gave reddit none of eleven." data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-searches-subreddits/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CPpf6ljW_vUQRU.webp" srcset="/_astro/heroImage.CPpf6ljW_ZWiIPB.webp 160w, /_astro/heroImage.CPpf6ljW_2ab9c.webp 224w, /_astro/heroImage.CPpf6ljW_Z2sxYJJ.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="3348" height="1750" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-searches-subreddits/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>
48ChatGPT Searches Individual Subreddits by Name</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A capture this week has ChatGPT targeting one subreddit directly, with a ten-year window, on a query where Bing returns no Reddit at all. Reddit was 48 of the 71 pages it fetched and won 6 of the 8 citations. Four days earlier, a different query gave Reddit none of eleven.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-25T00:00:00.000Z"> 25th August 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo" data-search="chatgpt rebuilt its search tool. i read the new language it speaks. between 16th and 20th august, chatgpt's search tool call went from json to a compact query language with freshness windows, domain targeting and separate verticals for products, places, images and widgets. i captured both sides of the change on the same account, with the same question. here's the full map, and what each part means for getting cited." data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-new-search-language/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DDljFfBP_2fCrl1.webp" srcset="/_astro/heroImage.DDljFfBP_Zd97Tr.webp 160w, /_astro/heroImage.DDljFfBP_Z1okTrM.webp 224w, /_astro/heroImage.DDljFfBP_2twU7w.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="2568" height="1256" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-new-search-language/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>ChatGPT Rebuilt Its Search Tool. I Read the New Language It Speaks.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Between 16th and 20th August, ChatGPT's search tool call went from JSON to a compact query language with freshness windows, domain targeting and separate verticals for products, places, images and widgets. I captured both sides of the change on the same account, with the same question. Here's the full map, and what each part means for getting cited.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-21T00:00:00.000Z"> 21st August 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo tools" data-search="how to track google ai mode traffic in search console four ways to surface ai mode and ai overview queries hiding in search console, from a custom regex to a free classifier that labels 100,000 queries per run." data-astro-cid-5tznm7mj> <a href="/blog/how-to-track-ai-mode-traffic/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BbzYZl7g_RJWgz.webp" srcset="/_astro/heroImage.BbzYZl7g_Z2fkkGC.webp 160w, /_astro/heroImage.BbzYZl7g_Z1HGJe4.webp 224w, /_astro/heroImage.BbzYZl7g_Z6bQf7.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1882" height="2152" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-to-track-ai-mode-traffic/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Track Google AI Mode Traffic in Search Console</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Four ways to surface AI Mode and AI Overview queries hiding in Search Console, from a custom regex to a free classifier that labels 100,000 queries per run.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-18T00:00:00.000Z"> 18th August 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo tools" data-search=""yes, go on": the ai conversations leaking into your search console a classifier for the ai conversations leaking into search console. seven kinds, from human replies and comparison questions to tracker bots and agent prompts, built from sixteen months of my own data and released as a free tool you run with one prompt." data-astro-cid-5tznm7mj> <a href="/blog/ai-mode-queries-search-console/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.ClAsudzG_ZLKFlK.webp" srcset="/_astro/heroImage.ClAsudzG_ZIIgtb.webp 160w, /_astro/heroImage.ClAsudzG_Z2rrwtm.webp 224w, /_astro/heroImage.ClAsudzG_ZWcHLW.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1572" height="730" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/ai-mode-queries-search-console/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>"Yes, Go On": The AI Conversations Leaking Into Your Search Console</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A classifier for the AI conversations leaking into Search Console. Seven kinds, from human replies and comparison questions to tracker bots and agent prompts, built from sixteen months of my own data and released as a free tool you run with one prompt.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-13T00:00:00.000Z"> 13th August 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo strategy" data-search="chatgpt already knows who's in the running before it searches chatgpt writes brand names into its own search query before it fetches a single page. i read the traffic across 60 conversations to work out when it happens, what being named is worth, and what actually gets you onto that list." data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-decides-before-it-searches/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.LrWmPy55_1E9Q3c.webp" srcset="/_astro/heroImage.LrWmPy55_ZWO6wG.webp 160w, /_astro/heroImage.LrWmPy55_ZoXAXN.webp 224w, /_astro/heroImage.LrWmPy55_Z1T2QPH.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="4442" height="2056" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/chatgpt-decides-before-it-searches/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>
48ChatGPT Already Knows Who's In The Running Before It Searches</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>ChatGPT writes brand names into its own search query before it fetches a single page. I read the traffic across 60 conversations to work out when it happens, what being named is worth, and what actually gets you onto that list.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-10T00:00:00.000Z"> 10th August 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo technical-seo tools" data-search="common crawl published a manual for being visible to ai. i automated it. common crawl's own ai visibility audit tells you to check your training data standing by hand. i automated it. my free checker reads 12 months of common crawl history for any domain or single page, dates the month a ccbot block appeared, tells you whether a cdn template wrote it, and hands you the fix." data-astro-cid-5tznm7mj> <a href="/blog/common-crawl-checker/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DS5K-sIg_Z2IQn6.webp" srcset="/_astro/heroImage.DS5K-sIg_Z24rVRY.webp 160w, /_astro/heroImage.DS5K-sIg_1CIXHx.webp 224w, /_astro/heroImage.DS5K-sIg_2bGBFN.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="3620" height="2302" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/common-crawl-checker/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Common Crawl Published a Manual for Being Visible to AI. I Automated It.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Common Crawl's own AI Visibility Audit tells you to check your training data standing by hand. I automated it. My free checker reads 12 months of Common Crawl history for any domain or single page, dates the month a CCBot block appeared, tells you whether a CDN template wrote it, and hands you the fix.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-08-02T00:00:00.000Z"> 2nd August 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo strategy" data-search="how perplexity actually picks sources (i read the stream, not the answers) i read perplexity's raw answer stream to see how it picks sources, which domains get cited by intent, and how to show up in and get cited by perplexity." data-astro-cid-5tznm7mj> <a href="/blog/how-perplexity-picks-sources/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.0oJ9BN64_2eOn9Y.webp" srcset="/_astro/heroImage.0oJ9BN64_RlpkL.webp 160w, /_astro/heroImage.0oJ9BN64_2rkdA8.webp 224w, /_astro/heroImage.0oJ9BN64_Z1uFhLK.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="4276" height="2418" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-perplexity-picks-sources/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How Perplexity Actually Picks Sources (I Read the Stream, Not the Answers)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I read Perplexity's raw answer stream to see how it picks sources, which domains get cited by intent, and how to show up in and get cited by Perplexity.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-07-27T00:00:00.000Z"> 27th July 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo tools" data-search="fanoutfox: a free chatgpt seo tool that shows how it picks sources fanoutfox is a free generative engine optimization (geo) tool and chatgpt rank tracker. it reads your own chatgpt session and shows the fan-out queries, the sources it fetched, who got cited, who got mentioned, and who beat you on each claim. free, local, one click." data-astro-cid-5tznm7mj> <a href="/blog/fanoutfox/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DQmXYQhc_7jtXF.webp" srcset="/_astro/heroImage.DQmXYQhc_Zjh7C1.webp 160w, /_astro/heroImage.DQmXYQhc_ZCd4hw.webp 224w, /_astro/heroImage.DQmXYQhc_ZDKjyO.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="2238" height="1352" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/fanoutfox/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>FanoutFox: A Free ChatGPT SEO Tool That Shows How It Picks Sources</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>FanoutFox is a free generative engine optimization (GEO) tool and ChatGPT rank tracker. It reads your own ChatGPT session and shows the fan-out queries, the sources it fetched, who got cited, who got mentioned, and who beat you on each claim. Free, local, one click.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-07-21T00:00:00.000Z"> 21st July 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo strategy" data-search="chatgpt changed how it picks sources while you were reading my last post a reader found a source pipeline i'd never seen, so i went back into chatgpt's network traffic 10 days after the first teardown. some of it had changed underneath me, i caught 2 of my own over-reaches, and i found the layer that shows who you lose citations to." data-astro-cid-5tznm7mj> <a href="/blog/how-chatgpt-picks-sources-part-2/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B85_k7wx_1gxEKs.webp" srcset="/_astro/heroImage.B85_k7wx_SzmdM.webp 160w, /_astro/heroImage.B85_k7wx_1TaNKF.webp 224w, /_astro/heroImage.B85_k7wx_Z1xH3eQ.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="940" height="784" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-chatgpt-picks-sources-part-2/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>
48ChatGPT Changed How It Picks Sources While You Were Reading My Last Post</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A reader found a source pipeline I'd never seen, so I went back into ChatGPT's network traffic 10 days after the first teardown. Some of it had changed underneath me, I caught 2 of my own over-reaches, and I found the layer that shows who you lose citations to.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-07-14T00:00:00.000Z"> 14th July 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="ai-seo strategy" data-search="how chatgpt actually picks sources (i read the network traffic, not the outputs) i read 2 days of chatgpt's raw network traffic to see how it picks sources, which domains get cited, and how to rank in and get cited by chatgpt." data-astro-cid-5tznm7mj> <a href="/blog/how-chatgpt-picks-sources/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.C-V3jqtV_Z2lGUL2.webp" srcset="/_astro/heroImage.C-V3jqtV_217lgk.webp 160w, /_astro/heroImage.C-V3jqtV_1I1Wqv.webp 224w, /_astro/heroImage.C-V3jqtV_Z2l58VM.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1288" height="636" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-chatgpt-picks-sources/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How ChatGPT Actually Picks Sources (I Read the Network Traffic, Not the Outputs)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I read 2 days of ChatGPT's raw network traffic to see how it picks sources, which domains get cited, and how to rank in and get cited by ChatGPT.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-06-24T00:00:00.000Z"> 24th June 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="i shipped agentic resource discovery on this site (and a client found me) google and 10 others shipped agentic resource discovery. i added an ai-catalog.json to this site, validated it against the official tool, and a reference client discovered my capabilities. here is the build and the cloudflare catch." data-astro-cid-5tznm7mj> <a href="/blog/agentic-resource-discovery/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.C_LLky5F_ZkuaWq.webp" srcset="/_astro/heroImage.C_LLky5F_PMCJ9.webp 160w, /_astro/heroImage.C_LLky5F_Z1Ezedt.webp 224w, /_astro/heroImage.C_LLky5F_ZDF5G.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="2864" height="1518" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/agentic-resource-discovery/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Shipped Agentic Resource Discovery on This Site (And a Client Found Me)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Google and 10 others shipped Agentic Resource Discovery. I added an ai-catalog.json to this site, validated it against the official tool, and a reference client discovered my capabilities. Here is the build and the Cloudflare catch.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-06-19T00:00:00.000Z"> 19th June 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="open knowledge format (okf): google's new markdown format for ai agents google shipped okf, the open knowledge format, a markdown standard for handing your content to ai agents. what it is, what it does and does not do, and how to generate your bundle free." data-astro-cid-5tznm7mj> <a href="/blog/open-knowledge-format/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CX9xeR-X_1z1CuB.webp" srcset="/_astro/heroImage.CX9xeR-X_Z1BvHHn.webp 160w, /_astro/heroImage.CX9xeR-X_MCBzP.webp 224w, /_astro/heroImage.CX9xeR-X_2h1XFi.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1280" height="720" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/open-knowledge-format/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Open Knowledge Format (OKF): Google's New Markdown Format for AI Agents</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Google shipped OKF, the Open Knowledge Format, a markdown standard for handing your content to AI agents. What it is, what it does and does not do, and how to generate your bundle free.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-06-14T00:00:00.000Z"> 14th June 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="how to get a google search profile from outside the us google search profiles are us only for now, but you can open yours from anywhere today. here is how, plus how claiming works and the noindex catch nobody mentions." data-astro-cid-5tznm7mj> <a href="/blog/google-search-profile-outside-us/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BMoDJhFo_Z46rcA.webp" srcset="/_astro/heroImage.BMoDJhFo_2goDH5.webp 160w, /_astro/heroImage.BMoDJhFo_ZoD9ND.webp 224w, /_astro/heroImage.BMoDJhFo_14KcgO.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1280" height="720" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/google-search-profile-outside-us/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Get a Google Search Profile From Outside the US</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Google Search profiles are US only for now, but you can open yours from anywhere today. Here is how, plus how claiming works and the noindex catch nobody mentions.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-06-05T00:00:00.000Z"> 5th June 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo" data-search="how to unlock "not provided" keywords in google analytics the 3 ways to recover your organic keyword data after google hid it in 2013. search console linking, bigquery pipelines, and third party tools compared honestly. includes a free open source skill whose methodology is fully inspectable, the opposite of the paid black boxes." data-astro-cid-5tznm7mj> <a href="/blog/not-provided-keywords-google-analytics/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BHmUPmmZ_Z23KW7s.webp" srcset="/_astro/heroImage.BHmUPmmZ_Z1BCtgJ.webp 160w, /_astro/heroImage.BHmUPmmZ_ZX5Scp.webp 224w, /_astro/heroImage.BHmUPmmZ_Z1Mvs8v.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="2065" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/not-provided-keywords-google-analytics/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Unlock "Not Provided" Keywords in Google Analytics</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>The 3 ways to recover your organic keyword data after Google hid it in 2013. Search Console linking, BigQuery pipelines, and third party tools compared honestly. Includes a free open source skill whose methodology is fully inspectable, the opposite of the paid black boxes.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-06-01T00:00:00.000Z"> 1st June 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="how to make your website agent-ready (and whether you actually should) a technical guide to the protocols, headers, and well-known files that make a website readable by ai agents. with the seo argument, the case study, and an honest look on whether you should bother yet." data-astro-cid-5tznm7mj> <a href="/blog/how-to-make-website-agent-ready/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DUzIp3vA_1NX7rv.webp" srcset="/_astro/heroImage.DUzIp3vA_ZqA3I1.webp 160w, /_astro/heroImage.DUzIp3vA_Z2nJQv7.webp 224w, /_astro/heroImage.DUzIp3vA_qadc4.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="639" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-to-make-website-agent-ready/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Make Your Website Agent-Ready (And Whether You Actually Should)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A technical guide to the protocols, headers, and well-known files that make a website readable by AI agents. With the SEO argument, the case study, and an honest look on whether you should bother yet.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-05-25T00:00:00.000Z"> 25th May 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy tools" data-search="i run my newsletter for $8/mo. the self-hosted alternative to beehiiv, kit, and mailerlite. the self-hosted alternative to beehiiv, kit (convertkit), mailerlite, substack, and resend. my newsletter runs on listmonk + aws ses for $8/mo with a cost comparison at 1k/5k/10k/50k subscribers." data-astro-cid-5tznm7mj> <a href="/blog/newsletter-cost-at-scale/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BRxH7qNH_1xBBpr.webp" srcset="/_astro/heroImage.BRxH7qNH_1xGBjN.webp 160w, /_astro/heroImage.BRxH7qNH_ayj7O.webp 224w, /_astro/heroImage.BRxH7qNH_VrtYP.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1490" height="574" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/newsletter-cost-at-scale/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Run My Newsletter for $8/mo. The Self-Hosted Alternative to Beehiiv, Kit, and MailerLite.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>The self-hosted alternative to Beehiiv, Kit (ConvertKit), MailerLite, Substack, and Resend. My newsletter runs on Listmonk + AWS SES for $8/mo with a cost comparison at 1k/5k/10k/50k subscribers.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-05-16T00:00:00.000Z"> 16th May 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo" data-search="the three lives of schema markup: a beginner'
48s guide to how google and llms actually use it schema markup is read by 3 completely different systems for 3 completely different purposes. most articles conflate them. here is what each one actually does, in plain english, with examples." data-astro-cid-5tznm7mj> <a href="/blog/three-lives-of-schema-markup/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DXeLyy7p_Z2tmOYt.webp" srcset="/_astro/heroImage.DXeLyy7p_f9f7e.webp 160w, /_astro/heroImage.DXeLyy7p_1uFNYx.webp 224w, /_astro/heroImage.DXeLyy7p_ZerxoE.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="500" height="500" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/three-lives-of-schema-markup/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>The Three Lives of Schema Markup: A Beginner's Guide to How Google and LLMs Actually Use It</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Schema markup is read by 3 completely different systems for 3 completely different purposes. Most articles conflate them. Here is what each one actually does, in plain English, with examples.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-05-13T00:00:00.000Z"> 13th May 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="webmcp: i made my website ai agent ready (here's how) a practical guide to implementing webmcp on your website. what it is, how it works, and a full walkthrough of adding mcp tools to a personal site so ai agents can interact with it directly." data-astro-cid-5tznm7mj> <a href="/blog/webmcp-implementation-guide/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.By5YPYtb_1IbJKX.webp" srcset="/_astro/heroImage.By5YPYtb_Z2lsrJf.webp 160w, /_astro/heroImage.By5YPYtb_Z1yHN7l.webp 224w, /_astro/heroImage.By5YPYtb_Z1ruSdQ.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1049" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/webmcp-implementation-guide/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>WebMCP: I Made My Website AI Agent Ready (Here's How)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A practical guide to implementing WebMCP on your website. What it is, how it works, and a full walkthrough of adding MCP tools to a personal site so AI agents can interact with it directly.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-05-12T00:00:00.000Z"> 12th May 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy tools" data-search="keyword hunt: i built a technical seo puzzle. keyword hunt is live. twenty single-word keywords cloaked using real technical seo, ai seo, and edge engineering. the first 10 to find all 20 get permanent elite status in the hall of fame." data-astro-cid-5tznm7mj> <a href="/blog/keyword-hunt-technical-seo-puzzle/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BuDqDMH9_ZGl46h.webp" srcset="/_astro/heroImage.BuDqDMH9_ZeG1UL.webp 160w, /_astro/heroImage.BuDqDMH9_Z1SWN71.webp 224w, /_astro/heroImage.BuDqDMH9_2rguFj.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="2342" height="1904" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/keyword-hunt-technical-seo-puzzle/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Keyword Hunt: I Built a Technical SEO Puzzle.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Keyword Hunt is live. Twenty single-word keywords cloaked using real technical SEO, AI SEO, and edge engineering. The first 10 to find all 20 get permanent Elite status in the Hall of Fame.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-05-07T00:00:00.000Z"> 7th May 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="i built an mcp that turns keyword clusters into seo content calendars a new mcp that turns a keyword insights clustering csv into a scheduled seo content calendar in 3 minutes. intent mismatch detection, excel export, free and open source." data-astro-cid-5tznm7mj> <a href="/blog/content-calendar-mcp-server/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DO3pKF-S_ZKkUmL.webp" srcset="/_astro/heroImage.DO3pKF-S_vyMgJ.webp 160w, /_astro/heroImage.DO3pKF-S_Zhx0k8.webp 224w, /_astro/heroImage.DO3pKF-S_Z2iJWTA.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="563" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/content-calendar-mcp-server/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>
48I Built an MCP That Turns Keyword Clusters Into SEO Content Calendars</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A new MCP that turns a Keyword Insights clustering CSV into a scheduled SEO content calendar in 3 minutes. Intent mismatch detection, Excel export, free and open source.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-23T00:00:00.000Z"> 23rd April 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="ga4 + gsc in bigquery: 6 tools that finally answer "what are my keywords worth?" connect google analytics 4 and search console data in bigquery through claude. revenue per keyword, content roi diagnosis, position value modelling, and 3 more tools. free, open source." data-astro-cid-5tznm7mj> <a href="/blog/google-analytics-bigquery-mcp-server/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DSGJcwIu_2amMR5.webp" srcset="/_astro/heroImage.DSGJcwIu_Zfw7Xj.webp 160w, /_astro/heroImage.DSGJcwIu_ZIFwvm.webp 224w, /_astro/heroImage.DSGJcwIu_ma2pt.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="690" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/google-analytics-bigquery-mcp-server/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>GA4 + GSC in BigQuery: 6 Tools That Finally Answer "What Are My Keywords Worth?"</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Connect Google Analytics 4 and Search Console data in BigQuery through Claude. Revenue per keyword, content ROI diagnosis, position value modelling, and 3 more tools. Free, open source.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-22T00:00:00.000Z"> 22nd April 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="cloudflare markdown for agents. i tracked every ai request for 44 days. cloudflare has a beta feature that serves clean markdown to ai agents. i enabled it, built a tracking layer, and logged every request for 44 days. 1,421 requests. claude was the second biggest consumer. here is everything i found." data-astro-cid-5tznm7mj> <a href="/blog/cloudflare-markdown-for-agents/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DZpp7fsd_Z1QG6cR.webp" srcset="/_astro/heroImage.DZpp7fsd_ZrRXWf.webp 160w, /_astro/heroImage.DZpp7fsd_Z24gWfV.webp 224w, /_astro/heroImage.DZpp7fsd_1dGJ86.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="934" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/cloudflare-markdown-for-agents/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Cloudflare Markdown for Agents. I Tracked Every AI Request for 44 Days.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Cloudflare has a beta feature that serves clean markdown to AI agents. I enabled it, built a tracking layer, and logged every request for 44 days. 1,421 requests. Claude was the second biggest consumer. Here is everything I found.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-19T00:00:00.000Z"> 19th April 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="how to run an llm locally. your data never leaves your machine. a practical guide to running ai models locally with ollama and lm studio. complete privacy, zero api costs, and surprisingly good performance on consumer hardware." data-astro-cid-5tznm7mj> <a href="/blog/run-llm-locally/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B9n2lrEP_ZYS8B3.webp" srcset="/_astro/heroImage.B9n2lrEP_1uLjcD.webp 160w, /_astro/heroImage.B9n2lrEP_Zqz39R.webp 224w, /_astro/heroImage.B9n2lrEP_2mov99.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="812" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/run-llm-locally/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Run an LLM Locally. Your Data Never Leaves Your Machine.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A practical guide to running AI models locally with Ollama and LM Studio. Complete privacy, zero API costs, and surprisingly good performance on consumer hardware.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-10T00:00:00.000Z"> 10th April 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="i tested 3 ways to forecast seo traffic. here is what actually works. i ran the same 486 days of gsc data through claude, arima, and meta prophet. all 3 landed within 10% of each other, but what you get around the numbers is completely different. free setup guide included." data-astro-cid-5tznm7mj> <a href="/blog/forecast-seo-traffic-prophet-claude-code/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BlpP9mi-_rxkPr.webp" srcset="/_astro/heroImage.BlpP9mi-_Z2oE2Cs.webp 160w, /_astro/heroImage.BlpP9mi-_Z1CaxWH.webp 224w, /_astro/heroImage.BlpP9mi-_Z1vlRYV.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1134" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/forecast-seo-traffic-prophet-claude-code/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Tested 3 Ways to Forecast SEO Traffic. Here Is What Actually Works.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I ran the same 486 days of GSC data through Claude, ARIMA, and Meta Prophet. All 3 landed within 10% of each other, but what you get around the numbers is completely different. Free setup guide included.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-06T00:00:00.000Z"> 6th April 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy" data-search="i made 10 seo predictions in 2020. here is my scorecard. in 2020, i published seo predictions on the moz blog. six years later, i grade myself honestly. what i got right, what i got wrong, and what nobody saw coming." data-astro-cid-5tznm7mj> <a href="/blog/seo-predictions-scorecard/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BkanqBY-_Z2vTxp1.webp" srcset="/_astro/heroImage.BkanqBY-_rSGGR.webp 160w, /_astro/heroImage.BkanqBY-_1mIjSL.webp 224w, /_astro/heroImage.BkanqBY-_1h7tuT.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1014" height="645" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/seo-predictions-scorecard/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Made 10 SEO Predictions in 2020. Here Is My Scorecard.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>In 2020, I published SEO predictions on the Moz blog. Six years later, I grade myself honestly. What I got right, what I got wrong, and what nobody saw coming.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-04-01T00:00:00.000Z"> 1st April 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="bigquery mcp server: 32 seo tools for your gsc + ga4 data warehouse connect claude to google bigquery with 32 built-in tools. revenue per keyword via ga4 + gsc blending, ml traffic forecasting, anomaly detection, anonymous query anal
48ysis, and more. free, open source, full setup guide." data-astro-cid-5tznm7mj> <a href="/blog/bigquery-mcp-server/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.u_3993JN_Z2i5L6U.webp" srcset="/_astro/heroImage.u_3993JN_Znpzy4.webp 160w, /_astro/heroImage.u_3993JN_2vm5m4.webp 224w, /_astro/heroImage.u_3993JN_ZVmo4o.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="981" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/bigquery-mcp-server/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>BigQuery MCP Server: 32 SEO Tools for Your GSC + GA4 Data Warehouse</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Connect Claude to Google BigQuery with 32 built-in tools. Revenue per keyword via GA4 + GSC blending, ML traffic forecasting, anomaly detection, anonymous query analysis, and more. Free, open source, full setup guide.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-29T00:00:00.000Z"> 29th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="google search console mcp: step by step setup guide (oauth + 20 free tools) connect claude to your google search console in 5 minutes with oauth. 20 free analysis tools: quick wins, content decay, cannibalisation, ctr benchmarks, alerting, and indexing api. full guide with screenshots." data-astro-cid-5tznm7mj> <a href="/blog/google-search-console-mcp-server/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.df1Y8eAv_Z2ky9ib.webp" srcset="/_astro/heroImage.df1Y8eAv_l5la3.webp 160w, /_astro/heroImage.df1Y8eAv_1KQBP8.webp 224w, /_astro/heroImage.df1Y8eAv_Z1kryMc.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="915" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/google-search-console-mcp-server/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Google Search Console MCP: Step by Step Setup Guide (OAuth + 20 Free Tools)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Connect Claude to your Google Search Console in 5 minutes with OAuth. 20 free analysis tools: quick wins, content decay, cannibalisation, CTR benchmarks, alerting, and Indexing API. Full guide with screenshots.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-22T00:00:00.000Z"> 22nd March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy" data-search="how i lost my youtube handle to a bot in a millisecond i released my youtube handle to transfer it between channels. a bot sniped it in seconds. here is what happened, what youtube did about it, and why you should never release a username on any platform." data-astro-cid-5tznm7mj> <a href="/blog/youtube-handle-stolen-by-bot/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B36KgIKt_Z6h9ST.webp" srcset="/_astro/heroImage.B36KgIKt_Z22FMNV.webp 160w, /_astro/heroImage.B36KgIKt_ZBTw8Q.webp 224w, /_astro/heroImage.B36KgIKt_Z1g4Xnw.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="900" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/youtube-handle-stolen-by-bot/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How I Lost My YouTube Handle to a Bot in a Millisecond</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I released my YouTube handle to transfer it between channels. A bot sniped it in seconds. Here is what happened, what YouTube did about it, and why you should never release a username on any platform.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-19T00:00:00.000Z"> 19th March 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy" data-search="how to get your dream handle on x (twitter) the full process of claiming an inactive x username, from premium plus to approval. how i went from @suganthanmn to @suganthan." data-astro-cid-5tznm7mj> <a href="/blog/get-your-dream-handle-on-x/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BWhHyAr-_16eim5.webp" srcset="/_astro/heroImage.BWhHyAr-_Ztd863.webp 160w, /_astro/heroImage.BWhHyAr-_Z1ysoGb.webp 224w, /_astro/heroImage.BWhHyAr-_2twyNq.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1736" height="1158" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/get-your-dream-handle-on-x/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Get Your Dream Handle on X (Twitter)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>The full process of claiming an inactive X username, from Premium Plus to approval. How I went from @Suganthanmn to @suganthan.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-14T00:00:00.000Z"> 14th March 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="how to use the wayback machine to recover lost content i lost 53 images during a site migration. the wayback machine cdx api got every single one back. here is the exact process, the commands, and a free claude skill that automates the whole thing." data-astro-cid-5tznm7mj> <a href="/blog/how-to-use-wayback-machine/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B3QeMq_L_ZU7br7.webp" srcset="/_astro/heroImage.B3QeMq_L_Z1s89WL.webp 160w, /_astro/heroImage.B3QeMq_L_2svqP.webp 224w, /_astro/heroImage.B3QeMq_L_76SRc.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1280" height="800" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-to-use-wayback-machine/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Use the Wayback Machine to Recover Lost Content</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I lost 53 images during a site migration. The Wayback Machine CDX API got every single one back. Here is the exact process, the commands, and a free Claude skill that automates the whole thing.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-09T00:00:00.000Z"> 9th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="how to connect the ahrefs mcp server to manus ahrefs has an official mcp server. manus has an official mcp integration. the connection didn't work out of the box. this is what happened, what i learned, and the working setup including a downloadable manus skill." data-astro-cid-5tznm7mj> <a href="/blog/ahrefs-mcp-server-manus-skill/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.YRo1ioaK_Z26gjEw.webp" srcset="/_astro/heroImage.YRo1ioaK_ZYhSBp.webp 160w, /_astro/heroImage.YRo1ioaK_1zwneT.webp 224w, /_astro/heroImage.YRo1ioaK_Z1PJcrf.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="847" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/ahrefs-mcp-server-manus-skill/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How to Connect the Ahrefs MCP Server to Manus</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Ahrefs has an official MCP server. Manus has an official MCP integration. The connection didn't work out of the box. This is what happened, what I learned, and the working setup including a downloadable Manus skill.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-07T00:00:00.000Z"> 7th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="rowboat gave me an ai coworker that actually remembers everything an honest guide to rowboat, the open source ai assistant that builds a private knowledge graph from your emails and meetings. how to set it up, why local models save you money, and what you can actually do with it." data-astro-cid-5tznm7mj> <a href="/blog/rowboat-ai-coworker-knowledge-graph/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage._bwKnjfu_2duEzO.webp" srcset="/_astro/heroImage._bwKnjfu_rsEkg.webp 160w, /_astro/heroImage._bwKnjfu_ZqXazN.webp 224w, /_astro/heroImage._bwKnjfu_2hng8P.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1966" height="1054" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/rowboat-ai-coworker-knowledge-graph/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Rowboat Gave Me an AI Coworker That Actually Remembers Everything</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>An honest guide to Rowboat, the open source AI assistant that builds a private knowledge graph from your emails and meetings. How to set it up, why local models save you money, and what you can actually do with it.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-06T00:00:00.000Z"> 6th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="i built a macos app with zero swift knowledge. here's how y
48ou can too. a beginner friendly guide to building macos and ios apps using ai vibe coding assistants in xcode. no swift experience needed. works with your existing claude or chatgpt subscription." data-astro-cid-5tznm7mj> <a href="/blog/build-macos-ios-apps-with-ai-xcode/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BNnyeo7Y_2dCaO4.webp" srcset="/_astro/heroImage.BNnyeo7Y_Z1xVPSS.webp 160w, /_astro/heroImage.BNnyeo7Y_2tROct.webp 224w, /_astro/heroImage.BNnyeo7Y_GEmLz.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="928" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/build-macos-ios-apps-with-ai-xcode/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Built a macOS App With Zero Swift Knowledge. Here's How You Can Too.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A beginner friendly guide to building macOS and iOS apps using AI vibe coding assistants in Xcode. No Swift experience needed. Works with your existing Claude or ChatGPT subscription.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-05T00:00:00.000Z"> 5th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="i built an ai skill that does my least favourite part of seo i open sourced a claude skill that turns any crawl export into a scored, prioritised technical seo audit with platform specific fix instructions. it replaces the 6 hours of spreadsheet work after every crawl." data-astro-cid-5tznm7mj> <a href="/blog/ai-skill-technical-seo-audit/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B4MXQPhP_18VqfX.webp" srcset="/_astro/heroImage.B4MXQPhP_Z1rr6YV.webp 160w, /_astro/heroImage.B4MXQPhP_Z1EPjQ.webp 224w, /_astro/heroImage.B4MXQPhP_ZEPhyw.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1280" height="720" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/ai-skill-technical-seo-audit/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Built an AI Skill That Does My Least Favourite Part of SEO</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I open sourced a Claude skill that turns any crawl export into a scored, prioritised technical SEO audit with platform specific fix instructions. It replaces the 6 hours of spreadsheet work after every crawl.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-03-04T00:00:00.000Z"> 4th March 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="how i added an ai chat to my personal website a step by step guide on how i built a rag powered ai assistant on my site using cloudflare vectorize, workers ai, and claude. it answers questions about my blog posts, opinions and personal knowledge." data-astro-cid-5tznm7mj> <a href="/blog/ai-chat-on-my-website/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.BuBoejMr_ZtKDHP.webp" srcset="/_astro/heroImage.BuBoejMr_Zl7iio.webp 160w, /_astro/heroImage.BuBoejMr_b1TuI.webp 224w, /_astro/heroImage.BuBoejMr_Z17Wq70.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1386" height="1260" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/ai-chat-on-my-website/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How I Added an AI Chat to My Personal Website</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A step by step guide on how I built a RAG powered AI assistant on my site using Cloudflare Vectorize, Workers AI, and Claude. It answers questions about my blog posts, opinions and personal knowledge.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-02-27T00:00:00.000Z"> 27th February 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="how our remote team saves $31,500/year using one platform instead of nine in 2024, i shared how roam replaced six tools for our remote team. two years later, it replaces nine. here is an updated look at what roam offers, what it costs, and why we still use it every day." data-astro-cid-5tznm7mj> <a href="/blog/roam-virtual-office-review/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.Dmpu3HIS_1HouNS.webp" srcset="/_astro/heroImage.Dmpu3HIS_Z2eulTO.webp 160w, /_astro/heroImage.Dmpu3HIS_Z1rBCjl.webp 224w, /_astro/heroImage.Dmpu3HIS_1edidd.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1008" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/roam-virtual-office-review/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How Our Remote Team Saves $31,500/Year Using One Platform Instead of Nine</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>In 2024, I shared how Roam replaced six tools for our remote team. Two years later, it replaces nine. Here is an updated look at what Roam offers, what it costs, and why we still use it every day.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-02-26T00:00:00.000Z"> 26th February 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="how i built this site: from wordpress to astro, tinacms, and cloudflare workers why i tore down my wordpress site and rebuilt it from scratch with astro 5, tinacms, and cloudflare workers. the story behind the decisions, the challenges, and what i learned." data-astro-cid-5tznm7mj> <a href="/blog/how-i-built-this-site/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CdzR2oM2_1mimio.webp" srcset="/_astro/heroImage.CdzR2oM2_udIuT.webp 160w, /_astro/heroImage.CdzR2oM2_g0lvz.webp 224w, /_astro/heroImage.CdzR2oM2_1DoTmK.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1248" height="832" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/how-i-built-this-site/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>How I Built This Site: From WordPress to Astro, TinaCMS, and Cloudflare Workers</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Why I tore down my WordPress site and rebuilt it from scratch with Astro 5, TinaCMS, and Cloudflare Workers. The story behind the decisions, the challenges, and what I learned.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-02-25T00:00:00.000Z"> 25th February 2026 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="openclaw for seo: what it is, how to set it up, and use cases that actually matter a practical guide to openclaw for seo. what it is, how it differs from chatgpt and claude, setup instructions, and real seo use cases." data-astro-cid-5tznm7mj> <a href="/blog/openclaw-for-seo/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DXK18O1V_1lBpFH.webp" srcset="/_astro/heroImage.DXK18O1V_1Jcgl6.webp 160w, /_astro/heroImage.DXK18O1V_Z1VzOLS.webp 224w, /_astro/heroImage.DXK18O1V_ZtqNh1.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="946" height="958" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/openclaw-for-seo/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>OpenClaw for SEO: What It Is, How to Set It Up, and Use Cases That Actually Matter</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A practical guide to OpenClaw for SEO. What it is, how it differs from ChatGPT and Claude, setup instructions, and real SEO use cases.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-02-23T00:00:00.000Z"> 23rd February 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="tools" data-search="i put openclaw inside my ray ban meta glasses. here is how. how visionclaw connects meta ray ban smart glasses to google gemini and openclaw for real time voice, vision, and agentic actions." data-astro-cid-5tznm7mj>
48 <a href="/blog/visionclaw-openclaw-meta-glasses/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CFFHFBzO_Z1Ct5Ro.webp" srcset="/_astro/heroImage.CFFHFBzO_Z2nHOwL.webp 160w, /_astro/heroImage.CFFHFBzO_2wpPqi.webp 224w, /_astro/heroImage.CFFHFBzO_2uRA90.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="3374" height="2060" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/visionclaw-openclaw-meta-glasses/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>I Put OpenClaw Inside My Ray Ban Meta Glasses. Here Is How.</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>How VisionClaw connects Meta Ray Ban smart glasses to Google Gemini and OpenClaw for real time voice, vision, and agentic actions.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2026-02-23T00:00:00.000Z"> 23rd February 2026 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Some assembly required</span> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo" data-search="logfile analysis for seo understanding how search engine crawlers interact with your website through server log analysis." data-astro-cid-5tznm7mj> <a href="/blog/logfile-analysis-seo/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CSyeZVt-_ZamumB.webp" srcset="/_astro/heroImage.CSyeZVt-_22Vjc3.webp 160w, /_astro/heroImage.CSyeZVt-_Z2bEnqI.webp 224w, /_astro/heroImage.CSyeZVt-_1XXnKR.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="745" height="373" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/logfile-analysis-seo/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Logfile Analysis for SEO</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Understanding how search engine crawlers interact with your website through server log analysis.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2020-07-21T00:00:00.000Z"> 21st July 2020 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy" data-search="what will it mean to do seo in 2020 and beyond? exploring the evolution of seo as search engines become smarter and user behaviour shifts across platforms." data-astro-cid-5tznm7mj> <a href="/blog/what-will-it-mean-to-do-seo-nowadays/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.J9_Vu2u0_Z2wxby2.webp" srcset="/_astro/heroImage.J9_Vu2u0_Z1lJL3t.webp 160w, /_astro/heroImage.J9_Vu2u0_1WSOv2.webp 224w, /_astro/heroImage.J9_Vu2u0_24HusN.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1130" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/what-will-it-mean-to-do-seo-nowadays/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>What Will It Mean to Do SEO in 2020 and Beyond?</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Exploring the evolution of SEO as search engines become smarter and user behaviour shifts across platforms.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2020-05-15T00:00:00.000Z"> 15th May 2020 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="strategy" data-search="seo competitor analysis: how do i find my niche rivals? how to effectively analyse your seo competitors to find opportunities and inform your strategy." data-astro-cid-5tznm7mj> <a href="/blog/seo-competitor-analysis/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CbKDNkCv_ZjufjJ.webp" srcset="/_astro/heroImage.CbKDNkCv_Z1HeoFR.webp 160w, /_astro/heroImage.CbKDNkCv_ZUBP2x.webp 224w, /_astro/heroImage.CbKDNkCv_ZNF56c.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1102" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/seo-competitor-analysis/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>SEO Competitor Analysis: How Do I Find My Niche Rivals?</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>How to effectively analyse your SEO competitors to find opportunities and inform your strategy.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-12-09T00:00:00.000Z"> 9th December 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="other" data-search="frustrating seo problems a deep dive into common and frustrating seo problems facing webmasters and seos, from zero-click results to gmb spam and shrinking organic landscapes." data-astro-cid-5tznm7mj> <a href="/blog/seo-problems/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CIFa1M2O_2fYz80.webp" srcset="/_astro/heroImage.CIFa1M2O_9MmkH.webp 160w, /_astro/heroImage.CIFa1M2O_1YxUFN.webp 224w, /_astro/heroImage.CIFa1M2O_1XXrIo.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="745" height="641" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/seo-problems/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Frustrating SEO Problems</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A deep dive into common and frustrating SEO problems facing webmasters and SEOs, from zero-click results to GMB spam and shrinking organic landscapes.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-09-15T00:00:00.000Z"> 15th September 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="other" data-search="a guide to outsourcing seo a comprehensive guide to outsourcing seo â from finding the right agency or freelancer to managing projects and measuring success." data-astro-cid-5tznm7mj> <a href="/blog/seo-outsource-guide/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DmdI8a-k_Z1bO7pP.webp" srcset="/_astro/heroImage.DmdI8a-k_Zmg76.webp 160w, /_astro/heroImage.DmdI8a-k_Z15BwHe.webp 224w, /_astro/heroImage.DmdI8a-k_ZwDSIX.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="745" height="481" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/seo-outsource-guide/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>A Guide to Outsourcing SEO</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A comprehensive guide to outsourcing SEO â from finding the right agency or freelancer to managing projects and measuring success.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-06-02T00:00:00.000Z"> 2nd June 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo" data-search="don't let your website redesign become an seo disaster a comprehensive guide to preserving your seo equity during a website redesign, covering url strategy, redirects, and post-launch monitoring." data-astro-cid-5tznm7mj> <a href="/blog/website-redesign-seo/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.B6_MpstH_Z1gEBF.webp" srcset="/_astro/heroImage.B6_MpstH_1g51Ye.webp 160w, /_astro/heroImage.B6_MpstH_22OFB8.webp 224w, /_astro/heroImage.B6_MpstH_29Tvw3.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="1067" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/website-redesign-seo/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Don't Let Your Website Redesign Become an SEO Disaster</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A comprehensive guide to preserving your SEO equity during a website redesign, covering URL strategy, redirects, and post-launch monitoring.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-05-06T00:00:00.000Z">
48 6th May 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="other" data-search="19 actionable seo tips a comprehensive guide with 19 actionable seo tips covering keyword research, featured snippets, video optimisation, local seo, schema markup, and more." data-astro-cid-5tznm7mj> <a href="/blog/seo-tips/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.CAmIGPVq_23Qbcq.webp" srcset="/_astro/heroImage.CAmIGPVq_Z2pnYyk.webp 160w, /_astro/heroImage.CAmIGPVq_1zxREt.webp 224w, /_astro/heroImage.CAmIGPVq_2hnYrn.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="745" height="486" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/seo-tips/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>19 Actionable SEO Tips</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>A comprehensive guide with 19 actionable SEO tips covering keyword research, featured snippets, video optimisation, local SEO, schema markup, and more.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-03-17T00:00:00.000Z"> 17th March 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo" data-search="why we need to start thinking about next-gen image formats exploring next-gen image formats like webp, jpeg 2000, and jpeg xr â why they matter for seo and web performance." data-astro-cid-5tznm7mj> <a href="/blog/next-gen-image-formats-for-seo/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.ffRqB2AQ_Z16JXEG.webp" srcset="/_astro/heroImage.ffRqB2AQ_Z1IArLh.webp 160w, /_astro/heroImage.ffRqB2AQ_nqEwE.webp 224w, /_astro/heroImage.ffRqB2AQ_1n1HVP.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="2560" height="1716" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/next-gen-image-formats-for-seo/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Why We Need to Start Thinking About Next-Gen Image Formats</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>Exploring next-gen image formats like WebP, JPEG 2000, and JPEG XR â why they matter for SEO and web performance.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-03-01T00:00:00.000Z"> 1st March 2019 </time> </div> </div> </article><article class="post-card archive-row" data-post-entry data-topics="technical-seo tools" data-search="rank math seo plugin review from an seo consultant (2026 update) i first reviewed rank math in 2019 when it was the new kid on the block. seven years, 3 million users, and an ai overhaul later, here is an honest update on where it stands in 2026." data-astro-cid-5tznm7mj> <a href="/blog/rank-math-seo-plugin-review-from-an-seo-guy/" class="archive-thumbnail" aria-hidden="true" tabindex="-1" data-astro-cid-5tznm7mj> <img src="/_astro/heroImage.DhWc-mC4_Z2uNhdQ.webp" srcset="/_astro/heroImage.DhWc-mC4_1QOhA8.webp 160w, /_astro/heroImage.DhWc-mC4_Z4w4Ln.webp 224w, /_astro/heroImage.DhWc-mC4_Z1LI9Gb.webp 336w" alt sizes="(max-width: 640px) 80px, 112px" loading="lazy" data-astro-cid-5tznm7mj="true" decoding="async" fetchpriority="auto" width="1600" height="811" class="archive-image"> </a> <div class="archive-row-content" data-astro-cid-5tznm7mj> <a href="/blog/rank-math-seo-plugin-review-from-an-seo-guy/" class="archive-title-link" data-astro-cid-5tznm7mj> <h3 class="archive-title" data-astro-cid-5tznm7mj>Rank Math SEO Plugin Review from an SEO Consultant (2026 Update)</h3> </a> <p class="post-card-desc archive-description" data-astro-cid-5tznm7mj>I first reviewed Rank Math in 2019 when it was the new kid on the block. Seven years, 3 million users, and an AI overhaul later, here is an honest update on where it stands in 2026.</p> <div class="archive-meta" data-astro-cid-5tznm7mj> <time datetime="2019-02-19T00:00:00.000Z"> 19th February 2019 </time> <span aria-hidden="true" data-astro-cid-5tznm7mj>·</span><span data-astro-cid-5tznm7mj>Quick setup</span> </div> </div> </article> </div> <!-- Empty state --> <p id="post-empty" class="hidden text-[var(--desc-ink)] text-[14.5px] mt-6" data-astro-cid-5tznm7mj> 49No posts match. <button type="button" id="post-reset" class="underline hover:no-underline cursor-pointer text-[var(--accent)] bg-transparent border-none p-0 font-[inherit] text-[14.5px]" data-astro-cid-5tznm7mj>Clear filters</button> </p> <!-- Pagination (client-side: every post stays in the HTML for crawlers, 50 pages are a display concern only) --> <nav class="archive-pagination" id="pagination" aria-label="Pagination" data-astro-cid-5tznm7mj> <button id="prev-page" class="pagination-direction" data-astro-cid-5tznm7mj>← Previous</button> <span id="page-numbers" data-astro-cid-5tznm7mj></span> <button id="next-page" class="pagination-direction" data-astro-cid-5tznm7mj>Next →</button> </nav> </div>
50<script type="module" src="/_astro/index.astro_astro_type_script_index_0_lang.5A3DyvO6.js"></script>
50 </main> <footer class="site-footer" data-astro-cid-sz7xmlte> <div class="footer-inner" data-astro-cid-sz7xmlte> <div class="footer-groups" data-astro-cid-sz7xmlte> <nav aria-label="Writing & tools" data-astro-cid-sz7xmlte><p data-astro-cid-sz7xmlte>Writing & tools</p><ul data-astro-cid-sz7xmlte><li data-astro-cid-sz7xmlte><a href="/ai-seo-research/" data-astro-cid-sz7xmlte>Research</a></li><li data-astro-cid-sz7xmlte><a href="/blog/" data-astro-cid-sz7xmlte>Articles</a></li><li data-astro-cid-sz7xmlte><a href="/notes/" data-astro-cid-sz7xmlte>Notes</a></li><li data-astro-cid-sz7xmlte><a href="/free-seo-tools/" data-astro-cid-sz7xmlte>Tools</a></li><li data-astro-cid-sz7xmlte><a href="/newsletter/" data-astro-cid-sz7xmlte>Newsletter</a></li><li data-astro-cid-sz7xmlte><a href="/feed/" data-astro-cid-sz7xmlte>RSS</a></li></ul></nav><nav aria-label="About & projects" data-astro-cid-sz7xmlte><p data-astro-cid-sz7xmlte>About & projects</p><ul data-astro-cid-sz7xmlte><li data-astro-cid-sz7xmlte><a href="/about/" data-astro-cid-sz7xmlte>About</a></li><li data-astro-cid-sz7xmlte><a href="/projects/" data-astro-cid-sz7xmlte>Projects</a></li><li data-astro-cid-sz7xmlte><a href="/contributions/" data-astro-cid-sz7xmlte>Contributions</a></li><li data-astro-cid-sz7xmlte><a href="/now/" data-astro-cid-sz7xmlte>Now</a></li><li data-astro-cid-sz7xmlte><a href="/uses/" data-astro-cid-sz7xmlte>Uses</a></li><li data-astro-cid-sz7xmlte><a href="/blogroll/" data-astro-cid-sz7xmlte>Blogroll</a></li></ul></nav><nav aria-label="Explore further" data-astro-cid-sz7xmlte><p data-astro-cid-sz7xmlte>Explore further</p><ul data-astro-cid-sz7xmlte><li data-astro-cid-sz7xmlte><a href="/ai-seo/" data-astro-cid-sz7xmlte>My approach to AI SEO</a></li><li data-astro-cid-sz7xmlte><a href="/ask/" data-astro-cid-sz7xmlte>Ask AI</a></li><li data-astro-cid-sz7xmlte><a href="/resources/" data-astro-cid-sz7xmlte>
50Resources</a></li><li data-astro-cid-sz7xmlte><a href="/ai/" data-astro-cid-sz7xmlte>AI</a></li><li data-astro-cid-sz7xmlte><a href="/mcp/" data-astro-cid-sz7xmlte>MCP</a></li></ul></nav> </div> <div class="footer-bottom" data-astro-cid-sz7xmlte> <p data-astro-cid-sz7xmlte>Client work through <a href="/work-with-me/" data-conversion-link="footer" data-agency-placement="footer" data-agency-topic="general" data-astro-cid-sz7xmlte>Snippet Digital</a>.</p> <div class="legal" data-astro-cid-sz7xmlte><span data-astro-cid-sz7xmlte>© 2026 Suganthan<sup title="SUGANTHAN, UK registered trade mark UK00004354704" data-astro-cid-sz7xmlte>®</sup></span><a href="/terms/" data-astro-cid-sz7xmlte>Terms</a><a href="/privacy/" data-astro-cid-sz7xmlte>Privacy</a></div> </div> </div> </footer> <!-- Back to top button --> <button id="back-to-top" aria-label="Back to top" class="fixed bottom-6 right-6 w-10 h-10 rounded-full bg-[rgb(var(--color-text))] text-[rgb(var(--color-bg))] flex items-center justify-center cursor-pointer border-none opacity-0 pointer-events-none transition-opacity duration-300 hover:opacity-80 z-50"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 15l-6-6-6 6"></path> </svg> </button>
50<script> 51 function initBackToTop() { 52 var btn = document.getElementById('back-to-top'); 53 if (!btn) return; 54 // Partial persistence (2026-09-02): the button only appears while 55 // the reader is scrolling UP, past the first screen, and hides 56 // again the moment they scroll down. Reading is a downward 57 // motion, so it stays off the text; on a phone the column is full 58 // width and the old always-on button sat on the last words of 59 // every line. 24px of upward travel before it shows, so a 60 // finger settling on the screen doesn't flash it. 61 var lastY = window.scrollY; 62 var upTravel = 0; 63 function show(on) { 64 btn.style.opacity = on ? '1' : '0'; 65 btn.style.pointerEvents = on ? 'auto' : 'none'; 66 } 67 function toggle() { 68 var y = window.scrollY; 69 if (y < lastY) upTravel += lastY - y; else upTravel = 0; 70 lastY = y; 71 show(y > 400 && upTravel > 24); 72 } 73 if (window._backToTopHandler) window.removeEventListener('scroll', window._backToTopHandler); 74 window._backToTopHandler = toggle; 75 window.addEventListener('scroll', toggle, { passive: true }); 76 btn.addEventListener('click', function () { 77 window.scrollTo({ top: 0, behavior: 'smooth' }); 78 }); 79 toggle(); 80 } 81 initBackToTop(); 82 document.addEventListener('astro:after-swap', initBackToTop); 83 </script>
83 <!-- Hide floating widgets (back-to-top, WebMCP) when footer is in view so they don't block footer links on mobile --> <style> 84 body.footer-in-view #back-to-top, 85 body.footer-in-view [data-webmcp-widget] { 86 opacity: 0 !important; 87 pointer-events: none !important; 88 transition: opacity 0.25s ease; 89 } 90 /* The WebMCP badge stays a desktop thing (2026-09-02). Below 640px 91 the reading column is the full viewport and the badge sat on the 92 first words of every line. Tools still register for agents; only 93 the human facing button goes. Important beats the widget's own 94 inline display: flex. */ 95 @media (max-width: 639px) { 96 [data-webmcp-widget] { 97 display: none !important; 98 } 99 } 100 </style>
100<script> 101 function initFooterObserver() { 102 var footer = document.querySelector('footer'); 103 if (!footer || !('IntersectionObserver' in window)) return; 104 if (window._footerObserver) window._footerObserver.disconnect(); 105 var io = new IntersectionObserver(function (entries) { 106 entries.forEach(function (entry) { 107 if (entry.isIntersecting) { 108 document.body.classList.add('footer-in-view'); 109 } else { 110 document.body.classList.remove('footer-in-view'); 111 } 112 }); 113 }); 114 window._footerObserver = io; 115 io.observe(footer); 116 } 117 initFooterObserver(); 118 document.addEventListener('astro:after-swap', initFooterObserver); 119 </script>
119 <!-- Unlisted pages skip enquiry tracking: it records the entry path, which 120 for a private link is the link itself, and forwards it with enquiries. -->
120<script type="module">const y=["entry_path","content_path","conversion_path"],h=["utm_source","utm_medium","utm_campaign","placement","topic"],f=/^[a-zA-Z0-9_-]{1,80}$/,v=/^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;function b(e){return typeof e=="string"&&e.length<=200&&/^\/[a-z0-9/._-]*$/.test(e)&&!e.includes("//")&&!e.includes("..")}function w(e){return typeof e=="string"&&f.test(e)}function k(e){return typeof e=="string"&&e.length<=120&&v.test(e)}function s(e){try{if(e===null||typeof e!="object"||Array.isArray(e))return{};const n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)return{};const o={},t=(a,g)=>{const u=Object.getOwnPropertyDescriptor(e,a);u&&"value"in u&&g(u.value)&&(o[a]=u.value)};for(const a of y)t(a,b);t("referrer_host",k);for(const a of h)t(a,w);return o}catch{return{}}}const c=window,A=document.documentElement.dataset.v2Preview==="true",l="suganthan-enquiry-context-v2";let r={};try{r=s(JSON.parse(sessionStorage.getItem(l)||"{}"))}catch{}const d=new URLSearchParams(location.search);let m="";try{m=new URL(document.referrer).hostname}catch{}r.entry_path||(r=s({entry_path:location.pathname,referrer_host:m,utm_source:d.get("utm_source"),utm_medium:d.get("utm_medium"),utm_campaign:d.get("utm_campaign")}));function p(){r=s(r);try{sessionStorage.setItem(l,JSON.stringify(r))}catch{}}c.__v2Attribution=()=>s({...r,conversion_path:location.pathname});const E=new Set(["agency_bridge_viewed","agency_link_clicked","enquiry_started","enquiry_accepted","preview_enquiry_completed"]);c.__v2Track=(e,n={})=>{if(!E.has(e))return;const o=s({...n,conversion_path:location.pathname});if(A){c.__v2Events=[...(c.__v2Events||[]).slice(-99),{name:e,properties:o}],console.debug("[V2 event]",e,JSON.stringify(o));return}c.rybbit?.event(e,o)};let i;function _(){if(document.documentElement.dataset.journeyBound)return;document.documentElement.dataset.journeyBound="true",i?.disconnect(),/^\/(blog|notes)\/[^/]+\/$/.test(location.pathname)&&(r.content_path=location.pathname),p();const e=new Map;i=new IntersectionObserver(n=>{n.forEach(o=>{const t=o.target;if(o.isIntersecting&&o.intersectionRatio>=.5){if(e.has(t))return;e.set(t,setTimeout(()=>{c.__v2Track?.("agency_bridge_viewed",{placement:t.dataset.agencyPlacement||"unknown",topic:t.dataset.agencyTopic||"general"}),i?.unobserve(t),e.delete(t)},1e3))}else clearTimeout(e.get(t)),e.delete(t)})},{threshold:.5}),document.querySelectorAll("[data-agency-bridge]").forEach(n=>i?.observe(n)),document.addEventListener("astro:before-swap",()=>{i?.disconnect(),e.forEach(clearTimeout)},{once:!0})}document.addEventListener("click",e=>{const n=e.target?.closest("a[data-conversion-link]");if(!n)return;const o=n.dataset.agencyPlacement||n.dataset.conversionLink||"unknown",t=n.dataset.agencyTopic||"general";r=s({...r,placement:o,topic:t,conversion_path:location.pathname}),p(),c.__v2Track?.("agency_link_clicked",{placement:o,topic:t,content_path:r.content_path||""})});_();document.addEventListener("astro:page-load",_);</script>
120 <!-- WebMCP widget (site-wide) -->
120<script src="/webmcp.js"></script>
120
120<script> 121 function initWebMCP() { 122 if (typeof WebMCP === 'undefined') return; 123 if (document.querySelector('[data-webmcp-widget]')) return; 124 125 var mcp = new WebMCP({ 126 color: '#527ED7', 127 position: 'bottom-left', 128 size: '32px', 129 padding: '20px' 130 }); 131 132 // Replace default trigger with the terminal icon. The cursor used 133 // to blink forever (mcpBlink); an infinite blink in the reader's 134 // peripheral vision on every page fails WCAG 2.2.2 and ignored 135 // reduced motion, so it's a still line now (2026-09-02). 136 setTimeout(function() { 137 var trigger = document.querySelector('.webmcp-trigger'); 138 if (!trigger) return; 139 140 // Dark mode fixes + blink animation 141 var style = document.createElement('style'); 142 style.textContent = [ 143 '.webmcp-content{background-color:#1e1e2e!important;border-color:#333!important;color:#e0e0e0!important}', 144 '.webmcp-content *{color:#e0e0e0!important}', 145 '.webmcp-content input{background:#2a2a3a!important;border-color:#444!important;color:#fff!important}', 146 '.webmcp-content .webmcp-status{background-color:#3a2a2a!important;color:#f0a0a0!important}', 147 '.webmcp-content .webmcp-registered-items{border-color:#444!important;background:#2a2a3a!important}', 148 '.webmcp-content .webmcp-tools-list,.webmcp-content .webmcp-prompts-list,.webmcp-content .webmcp-resources-list{border-color:#444!important}', 149 '@media(prefers-color-scheme:light){', 150 ' .webmcp-content{background-color:#fff!important;border-color:#e1e1e1!important;color:#333!important}', 151 ' .webmcp-content *{color:#333!important}', 152 ' .webmcp-content input{background:#fff!important;border-color:#ccc!important;color:#333!important}', 153 ' .webmcp-content .webmcp-status{background-color:#f8d7da!important;color:#721c24!important}', 154 ' .webmcp-content .webmcp-registered-items{border-color:#eee!important;background:#fff!important}', 155 '}' 156 ].join(''); 157 document.head.appendChild(style); 158 159 trigger.style.borderRadius = '8px'; 160 trigger.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width:18px;height:18px"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>'; 161 162 // Add "What is this?" link below trigger 163 var widget = trigger.parentElement; 164 if (widget) { 165 var link = document.createElement('a'); 166 link.href = '/mcp/'; 167 link.textContent = 'MCP'; 168 link.style.cssText = 'font-size:11px;letter-spacing:0.02em;color:rgb(var(--color-text));text-decoration:none;text-align:center;display:block;margin-top:3px;font-family:-apple-system,sans-serif;opacity:0.7;font-weight:700;width:32px;'; 169 widget.appendChild(link); 170 } 171 }, 100); 172 173 // Register tools 174 mcp.registerTool( 175 'search_posts', 176 'Search published blog posts on suganthan.com by keyword. Matches against title, description, and tags. Returns up to 20 results sorted by recency.', 177 { 178 type: 'object', 179 properties: { 180 query: { type: 'string', description: 'The search keyword or phrase' } 181 }, 182 required: ['query'] 183 }, 184 function(args) { 185 return fetch('/api/posts.json') 186 .then(function(res) { return res.json(); }) 187 .then(function(posts) { 188 var q = String(args.query || '').toLowerCase().trim(); 189 if (!q) { 190 return { content: [{ type: 'text', text: 'Provide a non-empty query.' }] }; 191 } 192 var matches = posts.filter(function(p) { 193 var hay = (p.title + ' ' + p.description + ' ' + (p.tags || []).join(' ')).toLowerCase(); 194 return hay.indexOf(q) !== -1; 195 }).slice(0, 20).map(function(p) { 196 return { title: p.title, slug: p.slug, url: p.url, description: p.description, pubDate: p.pubDate, tags: p.tags }; 197 }); 198 return { content: [{ type: 'text', text: JSON.stringify({ query: args.query, count: matches.length, results: matches }, null, 2) }] }; 199 }) 200 .catch(function(err) { 201 return { content: [{ type: 'text', text: 'Search failed: ' + (err && err.message ? err.message : 'unknown error') }] }; 202 }); 203 } 204 ); 205 206 mcp.registerTool( 207 'get_post', 208 'Get the full markdown content of a blog post by its slug. Returns title, description, dates, tags, and the raw markdown body.', 209 { 210 type: 'object', 211 properties: { 212 slug: { type: 'string', description: 'The blog post slug (e.g. "openclaw-for-seo")' } 213 }, 214 required: ['slug'] 215 }, 216 function(args) { 217 var slug = String(args.slug || '').trim(); 218 if (!slug) { 219 return Promise.resolve({ content: [{ type: 'text', text: 'Provide a non-empty slug.' }] }); 220 } 221 return fetch('/api/posts/' + encodeURIComponent(slug) + '.json') 222 .then(function(res) { 223 if (!res.ok) throw new Error('Post not found: ' + slug); 224 return res.json(); 225 }) 226 .then(function(post) {
227 var header = 'Title: ' + post.title + '\nURL: https://suganthan.com' + post.url + '\nPublished: ' + post.pubDate + (post.updatedDate ? '\nUpdated: ' + post.updatedDate : '') + (post.tags && post.tags.length ? '\nTags: ' + post.tags.join(', ') : '') + '\n\n'; 228 return { content: [{ type: 'text', text: header + (post.body || '') }] }; 229 }) 230 .catch(function(err) { 231 return { content: [{ type: 'text', text: 'Could not fetch post "' + slug + '": ' + (err && err.message ? err.message : 'unknown error') }] }; 232 }); 233 } 234 ); 235 236 mcp.registerTool( 237 'list_posts', 238 'List all published blog posts on suganthan.com with titles, slugs, URLs, dates, descriptions, and tags. Sorted by recency.', 239 { type: 'object', properties: {} }, 240 function() { 241 return fetch('/api/posts.json') 242 .then(function(res) { return res.json(); }) 243 .then(function(posts) { 244 return { content: [{ type: 'text', text: JSON.stringify({ count: posts.length, posts: posts }, null, 2) }] }; 245 }) 246 .catch(function(err) { 247 return { content: [{ type: 'text', text: 'Could not fetch post list: ' + (err && err.message ? err.message : 'unknown error') }] }; 248 }); 249 } 250 ); 251 252 mcp.registerTool('get_site_info', 'Get information about suganthan.com, the author, and topics covered.', { type: 'object', properties: {} }, function() { return { content: [{ type: 'text', text: JSON.stringify({ site: 'suganthan.com', author: 'Suganthan Mohanadasan', role: 'Co-founder of Snippet Digital (Reddit marketing & AI SEO agency) and Keyword Insights (keyword clustering SaaS)', location: 'Dubai, UAE', topics: ['SEO', 'AI tools for SEO', 'MCP servers', 'Claude Code skills', 'Reddit marketing', 'developer workflows', 'tool reviews'], social: { x: 'https://x.com/suganthan', linkedin: 'https://www.linkedin.com/in/suganthan-mohanadasan/', github: 'https://github.com/Suganthan-Mohanadasan' } }, null, 2) }] }; }); 253 } 254 initWebMCP(); 255 document.addEventListener('astro:after-swap', initWebMCP); 256 </script>
256 <!-- W3C / Chrome WebMCP native API (navigator.modelContext) -->
256<script> 257 (function () { 258 if (typeof navigator === 'undefined' || !('modelContext' in navigator)) return; 259 function registerNativeTools() { 260 try { 261 navigator.modelContext.provideContext({ 262 tools: [ 263 { 264 name: 'search_posts', 265 description: 'Search published blog posts on suganthan.com by keyword. Matches against title, description, and tags. Returns up to 20 results sorted by recency.', 266 inputSchema: { 267 type: 'object', 268 properties: { 269 query: { type: 'string', description: 'The search keyword or phrase' } 270 }, 271 required: ['query'] 272 }, 273 execute: async function (args) { 274 var res = await fetch('/api/posts.json'); 275 var posts = await res.json(); 276 var q = String((args && args.query) || '').toLowerCase().trim(); 277 if (!q) return { content: [{ type: 'text', text: 'Provide a non-empty query.' }] }; 278 var matches = posts.filter(function (p) { 279 var hay = ((p.title || '') + ' ' + (p.description || '') + ' ' + (p.tags || []).join(' ')).toLowerCase(); 280 return hay.indexOf(q) !== -1; 281 }).slice(0, 20).map(function (p) { 282 return { title: p.title, slug: p.slug, url: p.url, description: p.description, pubDate: p.pubDate, tags: p.tags }; 283 }); 284 return { content: [{ type: 'text', text: JSON.stringify({ query: args.query, count: matches.length, results: matches }, null, 2) }] }; 285 } 286 }, 287 { 288 name: 'get_post', 289 description: 'Get the full markdown content of a blog post by its slug. Returns title, description, dates, tags, and the raw markdown body.', 290 inputSchema: { 291 type: 'object', 292 properties: { 293 slug: { type: 'string', description: 'The blog post slug (e.g. "openclaw-for-seo")' } 294 }, 295 required: ['slug'] 296 }, 297 execute: async function (args) { 298 var slug = String((args && args.slug) || '').trim(); 299 if (!slug) return { content: [{ type: 'text', text: 'Provide a non-empty slug.' }] }; 300 var res = await fetch('/api/posts/' + encodeURIComponent(slug) + '.json'); 301 if (!res.ok) return { content: [{ type: 'text', text: 'Post not found: ' + slug }] }; 302 var post = await res.json(); 303 var header = 'Title: ' + post.title + '\nURL: https://suganthan.com' + post.url + '\nPublished: ' + post.pubDate + (post.updatedDate ? '\nUpdated: ' + post.updatedDate : '') + (post.tags && post.tags.length ? '\nTags: ' + post.tags.join(', ') : '') + '\n\n'; 304 return { content: [{ type: 'text', text: header + (post.body || '') }] }; 305 } 306 }, 307 { 308 name: 'list_posts', 309 description: 'List all published blog posts on suganthan.com with titles, slugs, URLs, dates, descriptions, and tags. Sorted by recency.', 310 inputSchema: { type: 'object', properties: {} }, 311 execute: async function () { 312 var res = await fetch('/api/posts.json'); 313 var posts = await res.json(); 314 return { content: [{ type: 'text', text: JSON.stringify({ count: posts.length, posts: posts }, null, 2) }] }; 315 } 316 }, 317 { 318 name: 'get_site_info', 319 description: 'Get information about suganthan.com, the author, and topics covered.', 320 inputSchema: { type: 'object', properties: {} }, 321 execute: async function () { 322 return { content: [{ type: 'text', text: JSON.stringify({ site: 'suganthan.com', author: 'Suganthan Mohanadasan', role: 'Co-founder of Snippet Digital and Keyword Insights', location: 'Dubai, UAE', topics: ['SEO', 'AI tools for SEO', 'MCP servers', 'Claude Code skills', 'Reddit marketing', 'developer workflows', 'tool reviews'], social: { x: 'https://x.com/suganthan', linkedin: 'https://www.linkedin.com/in/suganthan-mohanadasan/', github: 'https://github.com/Suganthan-Mohanadasan' } }, null, 2) }] }; 323 } 324 } 325 ] 326 }); 327 } catch (e) { 328 if (typeof console !== 'undefined' && console.warn) { 329 console.warn('navigator.modelContext.provideContext failed:', e); 330 } 331 } 332 } 333 registerNativeTools(); 334 document.addEventListener('astro:after-swap', registerNativeTools); 335 })(); 336 </script>
336
336<script> 337 function setupCopyButtons() { 338 document.querySelectorAll('.prose pre').forEach(function(pre) { 339 if (pre.querySelector('.copy-btn')) return; 340 var btn = document.createElement('button'); 341 btn.className = 'copy-btn'; 342 btn.setAttribute('aria-label', 'Copy code'); 343 btn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'; 344 btn.addEventListener('click', function() { 345 var code = pre.querySelector('code'); 346 if (!code) return; 347 navigator.clipboard.writeText(code.textContent).then(function() { 348 btn.classList.add('copied'); 349 btn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>'; 350 setTimeout(function() { 351 btn.classList.remove('copied'); 352 btn.innerHTML = '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>'; 353 }, 2000); 354 }); 355 }); 356 pre.appendChild(btn); 357 }); 358 } 359 document.addEventListener('DOMContentLoaded', setupCopyButtons); 360 document.addEventListener('astro:after-swap', setupCopyButtons); 361 </script>
361 </body> </html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.