343 Words of Furniture

Discoverability · Field note

343 Words of Furniture

My posts looked perfect in a browser and returned nothing to a machine that does not run one. Here is the measurement, the clause in the HTML standard that causes it, and the three separate times I believed I had fixed it.

  • Charleston, South Carolina
  • 3,031 posts audited
  • 32 repaired today
The number my own audit reported wrong 100% Structured-data coverage, declared complete on 30 August 2026.

Measured again this morning across all 3,031 published posts: 32 of the 155 posts using my full-canvas format still returned zero words of article to a parser that follows the specification. The audit had been checking that a block of structured data existed. It had never checked whether that block contained the article.

There are two readers of this page, and until this morning they were not reading the same page.

One of them runs a browser. It parses the HTML, attaches the shadow root, flattens the tree, lays out the type, and reads every word I wrote. That reader is Googlebot, and it has been fine the entire time.

The other reader fetches the bytes over HTTP and parses them with no rendering engine at all. That is most of what currently ingests the web on behalf of language models. On thirty-two of my posts, that reader received 343 words: a navigation menu, a row of share buttons, a category list, a tag list, and my author bio. Not one word of the essay.

I would rather show the measurement than describe it, so here is the actual output.

Figure 01 One post, two readers
Delivered to a browser 796 words of essay

Plus 343 words of site chrome. Renders correctly. Indexed by Google without incident.

Delivered to a spec-correct parser 0 words of essay

343 words of chrome, and nothing else. The article is present in the response body and unreachable by a conformant parse.

The Gate Attention Passes Through – John Rector · Skip to content · John Rector · Entrepreneur · Menu · Bio · Blog · Genre · Artificial Intelligence · Ideation · Cosmic Dance · Reality Equation · Poetry · Love · Press Release · Pay Online · Contact Us · Posted on September 8, 2026 · Share on X · Facebook · LinkedIn · WhatsApp · Email · Print · Pinterest · Tumblr · Like this · Categories · Tags · Author: John Rector …

Measured 8 September 2026 against the live URL of The Gate Attention Passes Through, using Python’s html.parser with template contents excluded per the HTML Living Standard. The word Ideation appears in that string — not from the essay, which never uses it, but from a menu item. That is the whole failure in one word: the only recognisable vocabulary a machine could recover was furniture.
Section one

The clause

My full-canvas format wraps each article in <template shadowrootmode="open">. That was a deliberate design decision and a good one. The template becomes a shadow root, the shadow root carries its own stylesheet, and nothing in my WordPress theme can leak in and break the layout. It gave me magazine typography on a platform that fights it.

It is also, by the letter of the standard, a filing cabinet.

The HTML Living Standard is not subtle about this. “The template contents of a template element are not children of the element itself.” And, two paragraphs later: “In a rendering, the template element represents nothing.” The contents are moved into a DocumentFragment whose owning document is a different document — the spec’s term of art is the appropriate template contents owner document. In Chrome, tpl.content.ownerDocument === document returns false. document.querySelector on anything inside returns null.

A browser resolves this at parse time by converting the template into a shadow root and attaching it to the host element. Then encapsulation takes over, and the answer comes out the same for a different reason: the text is visibly on screen, and document.body.innerText still does not contain it, because innerText walks child nodes and a shadow root is not a child.

The bytes were always in the response. A conformant parser is not being lazy when it refuses to see them. It is being correct.

That distinction is the sentence that let this run for eleven weeks. The article is right there in the HTML — you can curl it. True, and irrelevant. Presence in the response body is not readability. If the only reader that recovers your writing is one that ignores the standard, you have not published to the web. You have published to Chrome.

Section two

Who renders, and who will not say

Google renders, and documents it plainly. From Search Central, updated 4 March 2026: “When Google renders a page, it flattens the shadow DOM and light DOM content.” That single sentence is why every conventional signal on my site stayed healthy while a third of my recent writing was unreadable to everything else. Bing states that it renders too, though that claim now rests on blog posts from 2018 and 2019 — the current Webmaster Guidelines dropped the JavaScript section sometime after May 2025 and never replaced it.

The AI crawlers are the interesting case, and the honest answer is that almost none of them will tell you.

Figure 02 What each reader does with a shadow root
Reader Renders JavaScript Recovers shadow DOM text Basis
GooglebotYesYesGoogle Search Central, updated 4 Mar 2026: renders with headless Chromium and “flattens the shadow DOM and light DOM content.”
BingbotStated yesUndocumentedBing Webmaster Blog, Oct 2019: Bing adopted Microsoft Edge “to run JavaScript and render web pages.” Bing documents nothing about shadow DOM anywhere.
CCBot (Common Crawl)NoNoCommon Crawl FAQ, stated outright: “Currently, JavaScript is not executed and Cookies are not used.”
GPTBot / OAI-SearchBotUndocumentedUndocumentedOpenAI’s crawler documentation never mentions JavaScript, rendering, or a browser engine. Third-party measurement only.
ClaudeBotUndocumentedUndocumentedAnthropic’s crawler page is silent on rendering. It does not publish user-agent strings either.
PerplexityBotUndocumentedUndocumentedPerplexity’s crawler docs address robots.txt, not rendering. The widely quoted line that Perplexity “confirms it does not execute JavaScript” does not appear on any Perplexity page.
Compiled 8 September 2026 from each operator’s own documentation. “Undocumented” means the vendor says nothing — it is not a claim that the bot renders, and not a claim that it does not. Three of the six major AI-adjacent crawlers publish no position at all on the single behaviour that determines whether they can read a modern page.

The measurement everyone cites here is Vercel’s December 2024 analysis with MERJ: “The results consistently show that none of the major AI crawlers currently render JavaScript.” It found that ChatGPT’s and Claude’s crawlers do fetch JavaScript files — 11.50% and 23.84% of their requests respectively — and never execute them.

Two caveats I will state because most people quoting it do not. The percentages came primarily from one site, nextjs.org, plus the Vercel network. And the finding is twenty-one months old with no network-scale replication since; Cloudflare’s AI-crawler research measures request volume and status codes, not JavaScript execution. I do not need that study to be current for my own purposes, because I ran the parser against my own URLs and watched it come back empty. But if you are about to repeat “AI crawlers don’t render JavaScript” as settled fact, know that it rests on one measurement of one site in one December.

Section three

Three failures, each one narrower than the last

What makes this worth writing down is not the bug. It is that I fixed it twice and it was still broken this morning, and the reason changed each time.

  1. The format shipped without asking what a non-rendering reader would get

    I built the article inside a shadow root for good reasons and never once fetched the result without a browser. Discovered 30 August 2026, in an audit of all 2,962 posts then published: 121 used the format and 85 of them carried no structured data at all — roughly 98,500 words of published writing that looked immaculate in Chrome and returned navigation chrome to everything else.

    Cost: 85 posts · earliest affected 19 June 2026
  2. The rule was written down, and the thing doing the work never read it

    The fix was correct: a JSON-LD block in the light DOM, outside the template, carrying articleBody — the full plain text of the article. I wrote that down as mandatory. But a scheduled automation publishes several of my daily posts, and it had no idea the rule existed. So it recurred, quietly, in every post that automation produced.

    Cost: 31 posts · plus one published at 01:24 this morning
  3. The audit tested for the artifact instead of the outcome

    This is the one worth the essay. My audit script asked a single question of each post: does it contain the string #jr-article? All thirty-one of those posts did. They carried a complete-looking structured-data node — headline, description, publisher, dateModified, the works — with the articleBody field simply absent. They passed every check I had. They were unreadable the entire time.

    Cost: 52,785 words · invisible while reported as fixed

A check that tests for the artifact instead of the outcome will report a clean site forever.

Figure 03 Posts failing extraction, across three audits
85
32
0
30 Aug
of 121 full-canvas
8 Sep, morning
of 155 full-canvas
8 Sep, after
of 155 full-canvas
The first two bars were produced by different tests, and that is the finding rather than a footnote. The August audit asked whether a structured-data block existed. The September audit asked whether a spec-correct parser could recover the article. Had I run September’s test in August, the first bar would have been higher — I cannot say by how much, because I did not measure it and will not invent the number.
Section four

A rule is not a gate

I have now written this rule down three times. Writing it down accomplished nothing. Each time, the rule sat in a document, and the thing actually publishing the post — a script, an automation, a version of me at one in the morning — did not consult the document.

What finally worked is not a better-worded rule. It is a program that runs as the last step of every publish: fetch the live URL over plain HTTP, parse it the way the specification says to, and refuse to call the post finished unless a real article comes back with a real body. It takes about four seconds. It cannot be forgotten, because nothing is finished until it returns.

The difference is not diligence. It is where the check lives. A rule sits in a document that may never be read by whatever does the work. A gate sits in the path and cannot be walked around.

That generalises well past my blog. Most organisations adopting AI right now are writing rules — policies, guidelines, one-pagers about acceptable use — and then wondering why behaviour does not change. The rule is not in the path. Nobody has to walk through it to ship anything. If you want a standard held, put it where the work has to pass.

  • 3,031 posts
  • 155 full-canvas
  • 32 repaired today
  • 53,581 words restored
  • 33 citations recovered
  • 0 remaining
Section five

What this cost, and what it did not

It cost nothing in search. Rankings, impressions, indexing — untouched, because Google renders and Google was never the reader that failed. Any dashboard I own would have shown a healthy site for eleven weeks.

What it cost is the only thing this site is actually for. I write about making a business legible to machines. I run a lab in Charleston that helps other people do it. And a third of my recent output was arriving at the machines as a menu, a share bar, and a bio. There is no version of that which is a small irony.

It also cost the citations. Those thirty-two posts linked to primary sources — statutes, filings, government data. In the repaired structured data, thirty-three of those links came back as machine-readable citations. Before this morning, a model summarising my work could not have recovered a single one of them, which means it could not have told the difference between me and someone making it up.

The claim, and where it breaks

Already true
A conformant HTML parser cannot see inside a <template> or a shadow root; this is specified, not incidental. Google renders and recovers that content. Common Crawl states it does not render. OpenAI, Anthropic and Perplexity publish nothing on the question. All 3,031 of my published posts now pass a live extraction check.
What has to happen for the argument to hold
The AI crawlers that publish nothing have to actually not render — which is likely, and not proven by their own documentation. If OpenAI and Anthropic quietly moved to rendering fetchers, the practical stakes here shrink to Common Crawl and to anyone running a plain HTTP pipeline, which is still a great many people, but a smaller number than I am implying.
Where I am probably wrong
I am generalising from my own site, and my site is unusual — almost nobody hand-builds articles inside declarative shadow roots. The specific bug is rare. What I think generalises is the shape of it: a fix that was correct, a rule that was written, and an audit that measured the wrong thing, all coexisting for eleven weeks with a plainly broken outcome. If that shape turns out to be peculiar to me rather than common, this essay is a bug report wearing a suit.

What I deliberately left out

  • How much traffic or how many citations this actually cost. I have no server-side log of which crawlers fetched which posts and got nothing, so any number would be invented.
  • Whether the 30 August audit would have found more than 85 posts under September’s stricter test. It would have found more. I did not measure it, so I am not putting a figure on it.
  • Any claim that a specific AI product failed to cite me because of this. Plausible, unprovable, and not worth asserting.
  • The 2,712 posts on this site with an empty excerpt. Real, mostly pre-2026, and a different problem for a different day.

Sources

  1. WHATWG, HTML Living Standard §4.12.3, “The template element.” Template contents are not children of the element; the element represents nothing in a rendering.
  2. WHATWG, HTML Living Standard, “Parsing HTML — the in body insertion mode.” Normative handling of shadowrootmode.
  3. WHATWG, HTML Living Standard, “The innerText IDL attribute.” Rendered text collection walks child nodes.
  4. MDN, “<template>: The Content Template element.” Browser support for shadowrootmode: Chrome 111, Safari 16.4, Firefox 123.
  5. Google Search Central, “Understand JavaScript SEO basics,” updated 4 March 2026. Google flattens shadow DOM and light DOM when rendering.
  6. Google Search Central, “Fix search-related JavaScript problems.”
  7. Google Search Central, “Article structured data.” No required properties; articleBody is not among the supported ones.
  8. Schema.org, articleBody and BlogPosting. Valid property of Article, inherited by BlogPosting.
  9. Bing Webmaster Blog, “The new evergreen Bingbot,” 9 October 2019.
  10. Bing, Webmaster Guidelines (current). No JavaScript section.
  11. Common Crawl, FAQ. “Currently, JavaScript is not executed and Cookies are not used.”
  12. OpenAI, “Bots.” Silent on rendering.
  13. Anthropic, “Does Anthropic crawl data from the web?” Silent on rendering.
  14. Perplexity, “Perplexity Crawlers.” Silent on rendering.
  15. Vercel and MERJ, “The rise of the AI crawler,” 17 December 2024. Sample primarily nextjs.org.
  16. Cloudflare, “From Googlebot to GPTBot: who’s crawling your site in 2025,” 1 July 2025. Volume, not rendering.

Author: John Rector

John Rector is a Charleston-based entrepreneur, author, and AI strategist. He co-founded E2open, the supply-chain software company acquired for $2.1 billion in 2025, and in 2026 opened Charleston AI, a 3,000-square-foot lab that helps people and organizations understand and use artificial intelligence. He is the creator of The Reality Equation — a lecture series, book, and curriculum exploring attention, prediction, and how reality is experienced — and the author of more than two dozen books. He writes and speaks widely on artificial intelligence, attention, and the future of human work.

2 thoughts on “343 Words of Furniture

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from John Rector

Subscribe now to keep reading and get access to the full archive.

Continue reading