<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: lucian tudor</title>
    <description>The latest articles on DEV Community by lucian tudor (@lucian_tudor_303e1e12b9e5).</description>
    <link>https://dev.to/lucian_tudor_303e1e12b9e5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4063094%2F069815f3-87fe-4386-9084-692c1df5cf7e.png</url>
      <title>DEV Community: lucian tudor</title>
      <link>https://dev.to/lucian_tudor_303e1e12b9e5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucian_tudor_303e1e12b9e5"/>
    <language>en</language>
    <item>
      <title>I built a 126-page site optimised to be quoted by LLMs. Here is everything I shipped.</title>
      <dc:creator>lucian tudor</dc:creator>
      <pubDate>Tue, 04 Aug 2026 20:46:14 +0000</pubDate>
      <link>https://dev.to/lucian_tudor_303e1e12b9e5/i-built-a-126-page-site-optimised-to-be-quoted-by-llms-here-is-everything-i-shipped-38lp</link>
      <guid>https://dev.to/lucian_tudor_303e1e12b9e5/i-built-a-126-page-site-optimised-to-be-quoted-by-llms-here-is-everything-i-shipped-38lp</guid>
      <description>&lt;p&gt;A static Astro site built around one question — what does a page need to look like for a language model to quote it accurately? Separating the parts that definitely work from the parts that are still a bet.&lt;/p&gt;

&lt;p&gt;I built a website for a self-published book series recently. Small niche, unknown author, no existing audience, no backlinks, no budget. The kind of site that would normally take two years to rank for anything and might never rank at all.&lt;/p&gt;

&lt;p&gt;So I built it for a different surface. Not "rank #4 for a keyword", but "be the thing ChatGPT quotes when someone asks the question".&lt;/p&gt;

&lt;p&gt;This post is the whole approach: 126 pages, what I actually shipped, and — more useful — an honest split between the parts I know work and the parts that are still an educated guess. I have no results yet. The site is days old, not months, and Bing currently lists it as "discovered but not crawled" — exactly what you would expect for a domain with zero inbound links. So treat this as a build log, not a case study.&lt;/p&gt;

&lt;p&gt;I would rather post the method now and be told what I got wrong than post a victory lap in six months.&lt;/p&gt;

&lt;h2&gt;
  
  
  The premise
&lt;/h2&gt;

&lt;p&gt;Search and LLM retrieval reward different things.&lt;/p&gt;

&lt;p&gt;A search engine ranks documents. It wants to hand you ten links and let you decide. Authority, links and freshness dominate, which is why a new domain is stuck: the signals it lacks are the signals that matter most.&lt;/p&gt;

&lt;p&gt;A language model answering a question is doing something closer to extraction. It needs a passage that answers the question cleanly, that it can lift without mangling, and that it can attribute to an entity it recognises. Authority still matters — but &lt;em&gt;extractability&lt;/em&gt; is a real, separate axis, and it's one you can control completely on day one.&lt;/p&gt;

&lt;p&gt;That's the bet. Not that structure beats authority. That structure is the part a new site can actually compete on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack, briefly
&lt;/h2&gt;

&lt;p&gt;Astro in static mode, deployed to Cloudflare Workers static assets. Content in markdown via Astro's content collections, with typed frontmatter schemas.&lt;/p&gt;

&lt;p&gt;126 pages, all pre-rendered at build time. Exactly one dynamic endpoint (&lt;code&gt;/api/geo&lt;/code&gt;, which preselects an Amazon storefront). Everything else is a file on Cloudflare's edge.&lt;/p&gt;

&lt;p&gt;The content splits into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;42 Learn articles&lt;/strong&gt; across four topic pillars&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;60 glossary entries&lt;/strong&gt;, one term each&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5 FAQ pages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;19 hub, book and utility pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total JavaScript on a content page: near zero. The navigation menu, the FAQ accordions and the glossary search are all built on &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;/&lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; or degrade to plain visible content. This matters more than it sounds — see the "boring things" section.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: the boring things that definitely work
&lt;/h2&gt;

&lt;p&gt;Nothing here is novel. It's all just done properly, which is the entire point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-rendered HTML
&lt;/h3&gt;

&lt;p&gt;Some crawlers execute JavaScript. Many don't, or do it on a delayed second pass, or budget it heavily. A static build sidesteps the question entirely. The bytes that arrive contain the content.&lt;/p&gt;

&lt;p&gt;If you take one thing from this post, take this one. It's unglamorous and it dominates everything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  One question per page, answered in the first paragraph
&lt;/h3&gt;

&lt;p&gt;Every Learn and FAQ page is a single question. The title is the question. The H1 is the question. The first thing after the H1 is a 40–70 word direct answer that stands alone with no surrounding context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;question&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;investing,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;actually?"&lt;/span&gt;
&lt;span class="na"&gt;pillar&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;investing"&lt;/span&gt;
&lt;span class="na"&gt;answer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Investing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;buying&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;share&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;something&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;productive&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;—&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;companies,&lt;/span&gt;
  &lt;span class="s"&gt;property,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;loans&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;—&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hope&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;it&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;earns&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;money&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;over&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;time.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Unlike&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;saving,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;
  &lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;moves,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;it&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;can&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;move&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;down.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;You&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;are&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;being&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;paid,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;average&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;over&lt;/span&gt;
  &lt;span class="s"&gt;long&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;periods,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;accepting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;uncertainty&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;rather&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;than&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;being&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;clever."&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Investing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;means&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;owning&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;share&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;something&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;productive&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;
  &lt;span class="s"&gt;accepting&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;its&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;moves.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;return&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;payment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;uncertainty,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;not&lt;/span&gt;
  &lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;skill."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;answer&lt;/code&gt; field is enforced by the content schema, so a page cannot ship without one. Then the article goes deep underneath.&lt;/p&gt;

&lt;p&gt;The self-contained bit is the discipline. "As we saw above, this means…" is useless when lifted out of context. Every answer has to survive being quoted with nothing around it.&lt;/p&gt;

&lt;h3&gt;
  
  
  An entity graph, not a pile of schema
&lt;/h3&gt;

&lt;p&gt;This is the piece I see done badly most often. Most sites emit disconnected JSON-LD blobs — an &lt;code&gt;Article&lt;/code&gt; here, an &lt;code&gt;Organization&lt;/code&gt; there, no relationship between them.&lt;/p&gt;

&lt;p&gt;Instead, every page emits one &lt;code&gt;@graph&lt;/code&gt; where nodes reference each other by &lt;code&gt;@id&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@graph"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#author"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"knowsAbout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"personal finance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"saving"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"investing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"debt"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sameAs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"https://www.amazon.com/stores/author/…"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"…"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WebSite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#website"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"publisher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#author"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/learn/x#article"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#author"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"abstract"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"the same 40-70 word answer"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Person&lt;/code&gt; and &lt;code&gt;WebSite&lt;/code&gt; nodes are emitted by one component on every single page, so the entity facts are byte-identical site-wide. Pages add their own nodes on top. There is no way for one page to describe the author differently from another, because there is only one place the description exists.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sameAs&lt;/code&gt; is the highest-value line in the whole graph. It's what tells a search engine that the profile on one platform and the profile on another are one entity rather than three coincidences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Internal links that reflect the actual text
&lt;/h3&gt;

&lt;p&gt;The 60 glossary pages were originally reachable only from the glossary index. To a crawler that reads as "peripheral", and to a reader it means never encountering a definition at the moment they need it.&lt;/p&gt;

&lt;p&gt;So there's a component that scans the page's rendered text and links the glossary terms that genuinely appear in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;safe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;.*+?^${}()|[&lt;/span&gt;&lt;span class="se"&gt;\]\\]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s1"&gt;$&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;safe&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s?&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;b`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whole-word matching, so "share" doesn't fire inside "shareholder". Capped at five per page.&lt;/p&gt;

&lt;p&gt;Two deliberate choices. &lt;strong&gt;Nothing is injected into the prose&lt;/strong&gt; — automatic inline linking produces awkward anchors and text that reads as over-optimised. It's an honest list at the foot of the page instead. And the cap started at eight; I dropped it to five because a long block of machine-matched links &lt;em&gt;looks&lt;/em&gt; machine-made even when every match is legitimate.&lt;/p&gt;

&lt;h3&gt;
  
  
  IndexNow
&lt;/h3&gt;

&lt;p&gt;A 68-line script that reads the built sitemap and pings Bing, Yandex and Seznam on deploy. Verification is a single static file at the site root containing your key. That's it — no dashboard, no registration.&lt;/p&gt;

&lt;p&gt;Google has no equivalent, but Bing's index feeds ChatGPT and Copilot, which makes it disproportionately worth the twenty minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: the bets
&lt;/h2&gt;

&lt;p&gt;These I cannot justify with evidence. I shipped them because the cost is near zero and the asymmetry is good. Be appropriately sceptical — I am.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;abstract&lt;/code&gt; on every Article node
&lt;/h3&gt;

&lt;p&gt;The same 40–70 word answer that appears in the visible HTML also goes into schema as &lt;code&gt;abstract&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest assessment:&lt;/strong&gt; I have no evidence any model reads &lt;code&gt;abstract&lt;/code&gt; specifically. The argument for shipping it is that the marginal cost is one line in a component and the field is already in the visible text, so there's no cloaking risk and nothing to keep in sync. If it does nothing, it cost nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;llms.txt&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A markdown file at the site root stating the plain facts about the entity, what each section is for, and the canonical URLs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Honest assessment:&lt;/strong&gt; this is a proposed convention, not a standard. I'm not aware of evidence that major crawlers consume it today. It costs one file. The genuine side benefit is that writing it forces you to state, in one page, what your site actually claims to be — which surfaced two inconsistencies in my own copy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Signals in &lt;code&gt;robots.txt&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This one is a deliberate inversion of the usual advice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight robot_framework"&gt;&lt;code&gt;User-agent: *&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Content-Signal:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ai-train=yes,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;search=yes,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ai-input=yes&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Allow:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus explicit &lt;code&gt;Allow&lt;/code&gt; blocks for GPTBot, ClaudeBot, PerplexityBot, CCBot, Google-Extended and the rest.&lt;/p&gt;

&lt;p&gt;Most sites are busy blocking these. For an established publisher with traffic to protect, blocking is a coherent position. For an unknown author, absence from AI answers is a far bigger risk than inclusion in them. The calculus is genuinely different depending on who you are, and I think a lot of people are copying the default without doing that arithmetic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two things worth knowing if you go this route:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edge rules are enforced &lt;em&gt;before&lt;/em&gt; &lt;code&gt;robots.txt&lt;/code&gt; is ever fetched. Your CDN's bot-protection settings can silently override every &lt;code&gt;Allow:&lt;/code&gt; line you wrote. Your repo says one thing, your edge does another, and you have no idea.&lt;/p&gt;

&lt;p&gt;And some CDNs will manage &lt;code&gt;robots.txt&lt;/code&gt; for you. If &lt;code&gt;# BEGIN Cloudflare Managed content&lt;/code&gt; appears in the served file, it isn't yours any more. Diff what's served against what's in your repo, not what you think you deployed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two Cloudflare gotchas that cost me real time
&lt;/h2&gt;

&lt;p&gt;Both are specific to Workers static assets, and neither is obvious from the docs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redirects in Worker code never fire for files that exist.&lt;/strong&gt; A request matching a static asset is served at the edge without invoking your script at all. I wrote a &lt;code&gt;www&lt;/code&gt; → apex redirect in the Worker and it was dead code from the moment I shipped it — it only ran for URLs that didn't resolve to a file, which is to say never, for any real page. Host-level redirects belong in a Redirect Rule, which runs earlier in the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wildcard route will eat your subdomains.&lt;/strong&gt; This one cost a full day. I had &lt;code&gt;*.example.com/*&lt;/code&gt; on the Worker. Later I put 60 video files in R2 behind &lt;code&gt;media.example.com&lt;/code&gt;. Every single one returned 404.&lt;/p&gt;

&lt;p&gt;The bucket was fine. The files were fine, correct content types, correct sizes. The custom domain showed Active. The problem was that Worker routes take precedence over R2 custom domains, so the Worker was answering, finding no matching file, and serving &lt;em&gt;the website's own 404 page&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The tell was that the 404 was mine — my styling, my copy — on a URL that had nothing to do with the site. If you ever see your own error page on a subdomain that shouldn't be serving HTML at all, check your Worker routes before you touch anything else. I spent hours debugging a service that was working perfectly.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I would tell you to do
&lt;/h2&gt;

&lt;p&gt;If you have a new site and no authority, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ship server-rendered HTML.&lt;/strong&gt; Everything else is a rounding error next to this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One question per page, answered in the first 70 words, self-contained.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One entity graph with &lt;code&gt;@id&lt;/code&gt; references&lt;/strong&gt;, emitted from one component, identical everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fill in &lt;code&gt;sameAs&lt;/code&gt;.&lt;/strong&gt; It's the cheapest strong signal available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link internally based on what your text actually says&lt;/strong&gt;, not on a keyword map.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Then&lt;/strong&gt; worry about the speculative stuff.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Items 1–5 are just doing the fundamentals properly. If the LLM-extraction thesis turns out to be overblown, that work still pays off through ordinary search. That's the main reason I'd defend this approach even if the premise is wrong — the downside case is "you built a well-structured site."&lt;/p&gt;

&lt;h2&gt;
  
  
  What I don't know
&lt;/h2&gt;

&lt;p&gt;Whether any of Part 2 does anything. Whether question-first structure measurably improves citation rates versus simply being a good page. Whether &lt;code&gt;llms.txt&lt;/code&gt; will be a standard in a year or a footnote.&lt;/p&gt;

&lt;p&gt;I'll post numbers when I have them. If you've measured any of this properly, I'd genuinely like to hear it — particularly if you've found the structural stuff makes no difference and it really is authority all the way down.&lt;/p&gt;

&lt;p&gt;The site is &lt;a href="https://edmundwarde.com" rel="noopener noreferrer"&gt;edmundwarde.com&lt;/a&gt; if you want to look at the implementation. View source on any Learn page; the graph is all there.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>ai</category>
      <category>astro</category>
    </item>
  </channel>
</rss>
