Canonical Only in the Rendered DOM: Why to Move It to the HTML
- April 2, 2022
- Indexation, Canonical Issues

Canonical Only in the Rendered DOM: Why to Move It to the HTML
rel="canonical" in the raw HTML the server returns. The canonical only appears after JavaScript runs and builds the rendered DOM. Google can usually read a JS-injected canonical, but it adds a render dependency and delay, and many other crawlers and AI bots that do not run JavaScript will never see it at all. The fix is to output the canonical in the server-rendered HTML <head> so it is present before any script runs.What this means
A canonical tag tells search engines which URL is the preferred version of a page. Normally it sits in the <head> of the HTML your server sends back on the very first request. This issue fires when the canonical is missing from that raw response and is instead added later by JavaScript running in the browser. When the crawler compares the raw HTML to the fully rendered DOM, the canonical shows up only in the rendered version.
In other words, the page is relying on rendering to deliver one of its most important indexing signals. Anything that reads the page without executing scripts gets no canonical at all.
Why it matters
Google can process canonicals that appear in the rendered HTML after JavaScript has run. So in many cases the signal is eventually picked up. But Google's own JavaScript SEO guidance is clear that it does not recommend relying on JavaScript for canonicals and prefers them set in the raw HTML response. There are three concrete reasons this matters:
- Render dependency and delay. Google processes a page in two phases: it reads the raw HTML when it crawls, then renders the JavaScript later, sometimes much later. Canonicalization can be evaluated at both stages. A canonical that exists only after rendering is read only in the second, slower phase, which delays how quickly the signal is acted on.
- Conflict risk. Because the signal can be evaluated twice, a difference between what the raw HTML implies and what JavaScript ultimately sets can produce conflicting signals and unexpected indexing results.
- Non-rendering crawlers and AI bots miss it entirely. Many bots do not execute JavaScript. Bing, third-party SEO crawlers in their default mode, and a large share of AI and answer-engine crawlers read only the raw HTML. For all of them, a JS-only canonical simply does not exist, so they have no preferred-URL signal to follow.
How it gets flagged
Crawlers such as Screaming Frog and Sitebulb can fetch a page twice: once as raw HTML and once with JavaScript rendering enabled. They then compare the two. This issue is raised when no rel="canonical" is found in the raw HTML but one is present in the rendered DOM. It is a flag about where the canonical lives, not whether the canonical URL itself is correct.
How to fix it
Output the canonical in the server-rendered HTML <head> so it is present in the raw response, before any JavaScript runs. Do not inject it with client-side script. The raw-HTML canonical should match the URL your JavaScript would have set, so the signal is identical in both the crawl and render phases.
<!-- In the raw, server-rendered <head> -->
<head>
<link rel="canonical" href="https://example.com/your-page/">
</head>Practical paths depending on your stack: render the tag server-side (SSR), pre-render or statically generate the head, or set it in your CMS or template so it ships in the HTTP response. As a fallback you can serve the canonical in an HTTP Link response header. After the fix, ensure only one canonical tag exists on the page once rendered. If you genuinely cannot set the same canonical in the raw HTML, Google's guidance is to leave the canonical out of the raw HTML entirely rather than ship one value and rewrite it to a different value with JavaScript, since that is what creates conflicting signals. For deeper detail see our complete canonical tags reference and our JavaScript SEO and rendering guide.
False positives
A few situations look like this issue but are not problems on their own:
- The canonical is in the raw HTML but a crawler setting or caching layer served a stale or script-stripped version. Re-crawl with a fresh fetch and confirm against the actual server response.
- The page already sends the canonical as an HTTP
Linkheader. That is a valid raw-response signal even when no tag is in the HTML body, though some crawlers only inspect the markup. - A self-referencing canonical is added by the framework during SSR and the report compared a non-SSR view. Verify which version was tested.
FAQ
Will Google ignore my canonical if it is added by JavaScript?
Not necessarily. Google can read a canonical in the rendered HTML. The concern is the render dependency, the delay, the risk of conflicting signals, and the fact that non-rendering bots miss it. The raw HTML is the safer place for it.
Which crawlers and AI bots are affected?
Any bot that does not execute JavaScript reads only the raw HTML, so it sees no canonical here. This includes many AI and answer-engine crawlers. See our AI crawler map for which bots render and which do not.
Is an HTTP Link header an acceptable fix?
Yes. A canonical sent in the HTTP response header is part of the raw response and is read before rendering. A tag in the server-rendered head is the most widely supported option.
Not sure where your canonicals are being set?
An advanced SEO audit checks your raw HTML against the rendered DOM across your whole site and tells you exactly what to change.
Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.
About SEO ProCheck
Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.
Work With Me
Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.







