<?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: Jonas</title>
    <description>The latest articles on DEV Community by Jonas (@jonas_bra).</description>
    <link>https://dev.to/jonas_bra</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%2F4119849%2F9431f070-74c1-4610-99bf-ea407307c6fe.png</url>
      <title>DEV Community: Jonas</title>
      <link>https://dev.to/jonas_bra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonas_bra"/>
    <language>en</language>
    <item>
      <title>Raw HTML vs Rendered HTML: What AI Crawlers Actually See</title>
      <dc:creator>Jonas</dc:creator>
      <pubDate>Tue, 15 Sep 2026 18:48:51 +0000</pubDate>
      <link>https://dev.to/jonas_bra/raw-html-vs-rendered-html-what-ai-crawlers-actually-see-4l40</link>
      <guid>https://dev.to/jonas_bra/raw-html-vs-rendered-html-what-ai-crawlers-actually-see-4l40</guid>
      <description>&lt;p&gt;A web page can look complete in your browser and still send almost no useful content in its initial response.&lt;/p&gt;

&lt;p&gt;That sounds contradictory until you separate two things developers often treat as interchangeable: the HTML returned by the server and the document produced after a browser executes the page's JavaScript.&lt;/p&gt;

&lt;p&gt;For a person using a modern browser, the distinction is easy to miss. The browser runs the application, fetches data, updates the DOM, and presents the finished page.&lt;/p&gt;

&lt;p&gt;A crawler does not necessarily follow the same path. Some crawlers render JavaScript. Some render it later. Some use limited execution environments. Some primarily inspect the response they receive. A crawler may also stop when a script fails, a request is blocked, or rendering exceeds its resource budget.&lt;/p&gt;

&lt;p&gt;The useful question is therefore not just, “Does this page load?” It is, “Which version of this page is available to the system trying to read it?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Three versions of the same page
&lt;/h2&gt;

&lt;p&gt;It helps to distinguish three representations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial or raw HTML&lt;/strong&gt; is the response body returned by the server before client-side JavaScript runs. You can inspect it with an HTTP client or your browser's “View Source” feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser-rendered DOM&lt;/strong&gt; is the document after the browser has parsed the response and executed the relevant JavaScript. This is what you normally inspect in the Elements panel of developer tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crawler response&lt;/strong&gt; is what the server returns for a particular crawler request. It may match the initial HTML sent to a normal browser, but it does not have to. A site may route known crawlers to server-rendered or prerendered HTML while sending its client application to normal visitors.&lt;/p&gt;

&lt;p&gt;Consider a simplified client-rendered application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Acme Analytics&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After JavaScript runs, the DOM might contain a product heading, several paragraphs, pricing links, documentation navigation, structured data, and customer questions. None of that information is present in the response above.&lt;/p&gt;

&lt;p&gt;The browser has enough information to build the page. A system reading only the response does not.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSR and hydration are related, but not identical
&lt;/h2&gt;

&lt;p&gt;Client-side rendering (CSR) usually means that JavaScript creates most of the meaningful document in the browser. The server sends a shell and the client fetches or computes the content.&lt;/p&gt;

&lt;p&gt;Hydration starts from HTML that the server has already rendered. JavaScript attaches behavior to that existing markup. A hydrated page can therefore expose substantial content before JavaScript runs—provided the server response really contains that content.&lt;/p&gt;

&lt;p&gt;Framework choice alone does not tell you which result a crawler receives. React, Vue, Svelte, Angular, and similar tools can participate in client rendering, server rendering, static generation, or combinations of them. What matters is the deployed response for a specific URL.&lt;/p&gt;

&lt;p&gt;This is why statements such as “React sites are invisible to crawlers” are not useful. Some React sites return complete documents. Others return a thin shell. Many fall somewhere in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can disappear from the raw response?
&lt;/h2&gt;

&lt;p&gt;When the initial HTML is thin, the missing material is not limited to body copy. Common gaps include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The primary heading and descriptive text&lt;/li&gt;
&lt;li&gt;Product or article content loaded through an API&lt;/li&gt;
&lt;li&gt;Internal navigation and contextual links&lt;/li&gt;
&lt;li&gt;Canonical, description, or social metadata inserted by client code&lt;/li&gt;
&lt;li&gt;Structured data generated after mount&lt;/li&gt;
&lt;li&gt;Pagination or related-content links&lt;/li&gt;
&lt;li&gt;Text inside tabs, accordions, or client-side routes&lt;/li&gt;
&lt;li&gt;Error and empty states that replace expected content when a request fails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each gap has a different consequence. Missing body text reduces what a non-rendering reader can understand. Missing internal links affects discovery. Missing structured data removes an explicit machine-readable description, even when visible copy remains available.&lt;/p&gt;

&lt;p&gt;A character-count difference alone cannot tell you whether a page has a serious problem. A cookie banner can add thousands of unimportant characters, while a smaller difference can contain the only product description or links to deeper pages. The comparison needs both numbers and inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search crawlers and AI crawlers are not one audience
&lt;/h2&gt;

&lt;p&gt;It is tempting to divide the world into “Googlebot” and “AI bots,” but both groups contain systems with different purposes and capabilities.&lt;/p&gt;

&lt;p&gt;A search engine may fetch a document, schedule rendering separately, revisit it with another service, and combine the result with other signals. An AI company may operate different crawlers for search indexing, model training, user-requested retrieval, and link previews. An assistant answering a live question may also use a retrieval system that behaves differently from the company's general web crawler.&lt;/p&gt;

&lt;p&gt;Do not assume every crawler executes the same JavaScript—or that one successful render proves availability to all the others. Make the important public meaning available in useful HTML, then verify crawler-specific behavior with evidence.&lt;/p&gt;

&lt;p&gt;This matters beyond traditional search because AI visibility has at least two separate layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can a system access and understand the page?&lt;/li&gt;
&lt;li&gt;Does it choose to retrieve, cite, mention, or recommend that information for a particular question?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Improving the first layer does not guarantee the second. But a page that exposes no meaningful content creates an avoidable technical obstacle.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to compare the versions
&lt;/h2&gt;

&lt;p&gt;Start with the exact public URL, not a development route or a component in isolation.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Fetch the initial response
&lt;/h3&gt;

&lt;p&gt;Use an HTTP client and follow redirects deliberately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; https://example.com/product
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the body and inspect it as a document. Look for the page's main heading, a distinctive sentence, important links, canonical metadata, and structured data.&lt;/p&gt;

&lt;p&gt;Also record the final URL, status code, content type, redirect chain, and response size. A &lt;code&gt;200&lt;/code&gt; response only proves that the server returned something successfully; it does not prove that the response contains the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Inspect View Source
&lt;/h3&gt;

&lt;p&gt;“View Source” is a convenient representation of the server response. Do not confuse it with the Elements panel, which shows the live DOM after browser processing.&lt;/p&gt;

&lt;p&gt;Search the source for a sentence that visibly appears on the page. If it is absent, determine whether the browser adds it during rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Disable JavaScript
&lt;/h3&gt;

&lt;p&gt;Loading the page without JavaScript is a useful diagnostic, although it is not a perfect crawler simulation. It quickly reveals whether meaningful HTML exists before the application starts.&lt;/p&gt;

&lt;p&gt;The expected result depends on the product. A complex editor may reasonably require JavaScript to function. Its public landing page should still be understandable without waiting for an application API.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Render in a controlled browser
&lt;/h3&gt;

&lt;p&gt;Use Playwright, Puppeteer, or another browser automation tool to capture the resulting DOM. Define what “finished” means: &lt;code&gt;load&lt;/code&gt; may be too early, while network idle may never arrive on a page with analytics or live connections.&lt;/p&gt;

&lt;p&gt;Compare meaningful signals rather than performing a byte-for-byte diff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normalized visible text&lt;/li&gt;
&lt;li&gt;Headings&lt;/li&gt;
&lt;li&gt;Links and destinations&lt;/li&gt;
&lt;li&gt;Title, canonical, and description&lt;/li&gt;
&lt;li&gt;Robots directives&lt;/li&gt;
&lt;li&gt;Structured-data blocks&lt;/li&gt;
&lt;li&gt;Final URL and HTTP behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Repeat with relevant user agents
&lt;/h3&gt;

&lt;p&gt;User-agent testing can reveal routing differences, but it must be interpreted carefully. A different response does not automatically mean that a crawler will execute or accept it. Conversely, an identical response does not show what the crawler later renders.&lt;/p&gt;

&lt;p&gt;Check what your own infrastructure does. Avoid claiming knowledge of a crawler's internal rendering process based only on a user-agent request.&lt;/p&gt;

&lt;h2&gt;
  
  
  When prerendering helps
&lt;/h2&gt;

&lt;p&gt;Prerendering can be useful when a public, content-oriented route sends a thin application shell and changing the application's rendering architecture is not immediately practical.&lt;/p&gt;

&lt;p&gt;A rendering service can execute the page, capture useful HTML, cache it, and serve that representation to eligible crawlers. This can be especially practical for an established SPA where a framework migration would be disproportionate to the problem.&lt;/p&gt;

&lt;p&gt;The output should remain current, preserve correct statuses and redirects, and represent the same public content a visitor receives. Stale or materially different content creates a new problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  When prerendering is unnecessary
&lt;/h2&gt;

&lt;p&gt;Do not add a rendering layer merely because the site uses JavaScript.&lt;/p&gt;

&lt;p&gt;You probably do not need it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server rendering or static generation already returns the important content&lt;/li&gt;
&lt;li&gt;The raw and rendered versions differ only in interactive behavior&lt;/li&gt;
&lt;li&gt;The route is private or application-only and is not intended for discovery&lt;/li&gt;
&lt;li&gt;The missing content can be fixed directly with a smaller server-side change&lt;/li&gt;
&lt;li&gt;The page's public metadata, text, links, and structured data are already present&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best outcome is not “prerender everything.” It is “make each public page's important content reliably available with the least unnecessary complexity.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the response, not the framework label
&lt;/h2&gt;

&lt;p&gt;This raw-versus-rendered gap was one of the problems that led me to build Prerender Buddy. Its free checker compares the initial response, crawler-facing HTML, and browser-rendered page so the diagnosis is based on the URL's actual behavior rather than assumptions about its stack.&lt;/p&gt;

&lt;p&gt;You do not need a product to perform the basic investigation. &lt;code&gt;curl&lt;/code&gt;, browser source, developer tools, and a controlled browser script will take you a long way.&lt;/p&gt;

&lt;p&gt;The important habit is to stop treating “it loads in my browser” as the end of the test. A modern page is a sequence of representations. If discovery matters, inspect the representation that arrives before the interface becomes visible.&lt;/p&gt;

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