Technical SEO

Canonical via JavaScript, tested with four URLs

We tested whether Google picks up canonicals from the rendered HTML and how long that takes.

BlogoverviewPage APage BPage CPage D10 d23 d24 d34 dCanonical only in rendered HTML
Eoghan HennFirst published: June 5, 2018Last updated: October 15, 20268 min read
Experiment from 2018

The method and results come from our test in May and June 2018. The section What has changed since then describes where Google stands today.

In short
  • Google picks up a canonical set via JavaScript during rendering and recommends putting the canonical in the source code. If the source code already has one, JavaScript must not change it to a different URL.
  • In May 2018, a Google talk still said canonicals in the rendered HTML were ignored. We checked. A script in Google Tag Manager added a canonical pointing to the blog overview on four category and author pages, only in the rendered HTML. Two similar pages stayed unchanged as a control group.
  • Google canonicalized all four test pages, after 10, 23, 24 and 34 days. Search Console still showed the pages with a different status.

Why we ran the test

At Google I/O in May 2018 there was a talk on JavaScript SEO. It said that Google does not look for canonical tags in the rendered HTML. That did not match our test with Google Tag Manager from the year before, where a canonical added via Tag Manager had worked.

That earlier finding was based on a single URL, though. With canonicals, this is a known problem. A canonical only works between very similar pages, and Google often canonicalizes those even without a canonical. A single hit can therefore be chance. So the day after the talk we set up the test again, with more pages and a control group.

Our question was how Google treats websites that depend on client-side JavaScript. Whether you should set canonicals via JavaScript is a different question. The answer to that comes further down.

Test setup

On 11 May 2018, Google Tag Manager added a canonical pointing to the blog overview on four pages. The source code of these pages contained no canonical pointing to the overview. The script looked roughly like this.

// Custom HTML tag in Google Tag Manager, triggered only on the test pages <script> var l = document.createElement('link'); l.rel = 'canonical'; l.href = 'https://www.example.com/blog/'; document.head.appendChild(l); </script>
PageRoleStatus on 11 May 2018
English category “SEO experiments”Test, canonical to the blog overviewnot canonicalized
English category “SEO for website relaunches”Test, canonical to the blog overviewnot canonicalized
German category “SEO für Website-Relaunches”Test, canonical to the German blog overviewnot canonicalized
German author page of Michael WeberTest, canonical to the blog overviewalready canonicalized by Google to the English author page (missing hreflang)
German author page of Eoghan HennControl, no canonical–
English author page of Michael WeberControl, no canonical–

The control pages were meant to show whether Google would merge such pages into the overview even without our canonical. If that had happened, the test would have proved nothing. At the time, we checked the status with the info: search query, which showed the URL Google had chosen.

Result

DateDays after insertionPage canonicalized
21 May 201810English category “SEO for website relaunches”
3 June 201823English category “SEO experiments”
4 June 201824German category, to the German blog overview
13 June 201834German author page of Michael Weber

All four test pages ended up on the target of the canonical added via JavaScript. As far as we know, none of these pages had ever been canonicalized that way before.

Requesting indexing barely helped

On 11 May we used “Fetch and render” with “Request indexing” in Search Console for all test pages. On 22 May we did the same for the blog overviews with all linked pages, and on 1 June once more for the three pages that had not been canonicalized by then. For new URLs this usually works almost immediately. Here the first request had no visible effect. The request on 1 June may have triggered the changes on 3 and 4 June. Perhaps Google also has to render a page several times before it picks up an inserted canonical.

Search Console showed something else

In the index coverage report of the time, the canonicalized test pages were listed as “Submitted URL not selected as canonical”. We would have expected “Alternate page with proper canonical tag”. Our explanation was that the report followed the official rules. It overlooked canonicals that only appear in the rendered HTML, even though Search used them.

Our conclusion

  • Google used canonicals that only appeared in the rendered HTML, contrary to what the talk said.
  • For some pages, it took more than three weeks for the canonical to be picked up.
  • “Request indexing” did not noticeably speed up rendering.
  • Search Console ignored the inserted canonicals in its reports.
  • The statement in the talk may have been based on a misunderstanding or a mistake.

What has changed since then?

Google now describes this behavior itself. According to its JavaScript SEO documentation, Google Search picks up a canonical inserted via JavaScript during rendering. It is still not recommended. Google advises setting the canonical in the HTML. If you set it via JavaScript, it should name the same URL as the canonical in the source code. If that is not possible, leave it out of the source code. In the end, the page may only contain one canonical. According to Google, multiple or conflicting canonicals lead to unexpected results.

The tools of that time no longer exist in that form. Today, the URL Inspection tool in Search Console shows the canonical URL Google has selected, next to the canonical you declared. The index coverage report is now called “Page indexing”. We have not re-tested how it handles canonicals from the rendered HTML today. According to Vercel (December 2024), AI crawlers such as GPTBot and ClaudeBot do not execute JavaScript and do not see such a canonical at all. The basics are covered in the canonical tag guide.

How to check your canonicals

  1. Set the canonical in the source code, with an absolute URL and only once in the head.
  2. Check whether a script, a plugin or a tag in Tag Manager adds a second canonical or changes the existing one.
  3. Compare the source code and the rendered HTML. The following script shows both values.
  4. Use URL Inspection to check which URL Google has selected as canonical.
// Run in the browser console. Shows the canonical in the source code and in the DOM. (async () => { const raw = await (await fetch(location.href)).text(); const src = new DOMParser().parseFromString(raw, 'text/html'); const get = d => [...d.querySelectorAll('link[rel="canonical"]')].map(l => l.getAttribute('href')); console.table({ source: get(src).join(' | ') || '–', rendered: get(document).join(' | ') || '–' }); })();

Common mistakes

  • The source code contains a self-referencing canonical, and JavaScript changes it to a different URL.
  • A tag in Tag Manager adds a canonical, and the old one stays in place.
  • A script closes the head too early. The canonical then ends up in the body and does not count.
  • A result is judged after a few days, even though Google needs longer to render.

FAQ

Does Google respect a canonical set via JavaScript?

Yes. In our 2018 test, Google canonicalized all four test pages according to the inserted canonical. Today, Google's documentation confirms that Search picks up an inserted canonical during rendering.

May JavaScript change an existing canonical?

Google advises against it. The canonical set via JavaScript should name the same URL as the one in the source code. If there is none in the source code, JavaScript may set it.

Can I set canonicals with Google Tag Manager?

Technically yes, as the test shows. It is not much use as a permanent solution, because the tag only takes effect after rendering and AI crawlers without rendering do not see it.

How long does it take for Google to pick up a JavaScript canonical?

In our test, 10 to 34 days. This is a measurement from 2018 on less important pages.

Where can I see which canonical Google has chosen?

In the URL Inspection tool in Search Console, under “Google-selected canonical”.

The searchVIU SEO Crawler fetches your entire website every week, with Google Chrome and including JavaScript. For every URL you see the canonical in the source code and in the rendered HTML, compared with the last crawl. The canonicals topic report shows where the two differ. Find out more on the SEO Crawler page.

Request a demo

Sources

Retrieved on October 15, 2026. If something is out of date or missing, let us know.

  1. Google, Understand the JavaScript SEO basics: https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics · As of Mar 4, 2026
  2. Google, How to specify a canonical URL: https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls · As of Jul 10, 2026
  3. Search Console Help, URL Inspection tool: https://support.google.com/webmasters/answer/9012289 · Retrieved Oct 15, 2026
  4. Search Console Help, Page indexing report: https://support.google.com/webmasters/answer/7440203 · Retrieved Oct 15, 2026
  5. Vercel, The rise of the AI crawler: https://vercel.com/blog/the-rise-of-the-ai-crawler · Dec 17, 2024