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.
AI Crawler List 2026: Every User-Agent, robots.txt per Bot
44 AI user-agent tokens with owners and IP lists, which bots ignore robots.txt, three copy-paste presets, and a re-scan showing zero drift in September 2026.
· 24 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
How to Help AI Understand Your Content with JSON-LD
LLMs ground answers in structured data. With schema.org markup, the model sees a typed object — author, date, headline. Here's the canonical setup.
· 11 min read
The Invisible Tags Shaping Your AI Citations
title, meta description, og:image, canonical — four tags decide if ChatGPT and Perplexity render your brand on the citation card. The bundle.
· 11 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.