Writing
Long-form notes on things I had to work out in production: how AI crawlers read a page, what Core Web Vitals actually punish, and where WordPress and Next.js meet.
OAI-SearchBot vs GPTBot vs ChatGPT-User: Which to Block
OpenAI documents four crawlers, and only two have a robots.txt control. See what each does, who blocks them in 59 real robots.txt files, and how to verify IPs.
· 14 min read
llms.txt WordPress Plugins: Yoast vs Rank Math vs AIOSEO
We tested Yoast, Rank Math and AIOSEO on identical WordPress sites and compared what each writes to llms.txt, from caps to freshness.
· 16 min read
AI Crawler List 2026: 44 User-Agent Tokens for robots.txt
robots.txt user-agent list, updated 29 Oct 2026: copy all 44 AI crawler tokens, see which bots ignore robots.txt, and pick one of three presets.
· 30 min read
Skip the AI Visibility Checker: Audit Your Site by Hand
Run the same eight checks a paid AI visibility checker runs, for free: llms.txt, robots.txt, JSON-LD, and real 2026 baselines to compare your site against.
· 13 min read
GEO vs SEO vs AEO — What Actually Changes in Your Workflow
I scanned 93 pages ranking for AEO and GEO queries to see whether the people explaining the difference follow their own advice. Only 25.8% did.
· 11 min read
Embeddings: How AI Search Turns Your Page Into 384 Numbers
AI search doesn't match keywords - it compares vectors. Turn your text into an embedding, run cosine similarity live, and watch stuffing win the wrong race.
· 14 min read
The Temporal API: Fixing 30 Years of JavaScript Dates
JavaScript's Date has shipped the same bugs since 1995 — mutation, zero-based months, no real time zones. Temporal fixes them, run every example live.
· 9 min read
How I Added llms.txt to My Next.js Blog in 15 Minutes
How llms.txt works, why 52.7% of pages ranking for AEO and GEO queries now serve one, and two ways to ship it on a Next.js blog in 15 minutes.
· 13 min read
The 3-Word Tag That Hides Your Best Pages from AI
Three words in `<head>` can hide your best article from ChatGPT, Claude, and Perplexity — even if Google still shows it. The silent AEO killer.
· 10 min read
Recency and Authority — Two Fields AI Uses to Trust You
Before quoting your article, AI runs two checks — is it fresh, and who wrote it. Both ride on machine-readable signals. Here's the canonical setup.
· 8 min read
What I write about
Most of what is here comes out of the same recurring problem: the gap between a page a human finds useful and a page a machine can parse. That gap used to be a search-engine concern with well-known answers. It stopped being well-known when the readers became language models.
Three threads run through the archive:
- How machines read pages —
llms.txt, JSON-LD, semantic heading structure, embeddings, the meta tags that quietly exclude you from AI answers. Start with Why your site doesn't show in ChatGPT and Perplexity. - Measuring it rather than guessing — How to audit AI visibility walks the audit this site runs on itself, with the AEO Checker extension doing the per-page part.
- The platform underneath — Next.js, WordPress, Core Web Vitals, and the occasional language feature worth the migration, like the Temporal API.
How to read it
Every post has a machine-readable twin at the same URL with .md appended —
this index included. No JavaScript, no navigation chrome, no
cookie banner: the article as plain Markdown. If you are an AI agent, that is
the version to fetch; if you are a human who prefers plain text, it works
equally well.
The same applies site-wide. /llms.txt is the map, every page
declares its own .md alternate, and nothing is hidden behind a paywall or a
sign-up.
Where an article explains a mechanism you can poke at, there is usually a browser-only tool for it — the embeddings piece has a live playground, and the AEO articles have the AEO Checker extension. Start from the AEO pillar page if you want the whole cluster in reading order.
FAQ
How often do you publish?
Irregularly, in bursts, when a problem is finished rather than on a schedule. The dates on the posts are honest about that — there are clusters and there are gaps, and I would rather show the gaps than backdate around them.
Can I get these by RSS?
Yes — /blog/feed.xml carries every post. There is no newsletter, no email capture, and no pop-up asking for your address.
Why does every post have a .md version?
Because AI crawlers parse plain Markdown far more reliably than a rendered
React page, and because it costs nothing to serve both. The HTML page stays
canonical for Google; the .md twin is a courtesy to anything that would
rather skip the DOM.
Can I republish or quote these posts?
Quote freely with a link back. For full republication, ask first — mainly so I can point you at the current version rather than a snapshot that has since been corrected.