What does Google say about SEO? /
Quick SEO Quiz

Test your SEO knowledge in 5 questions

Less than a minute. Find out how much you really know about Google search.

🕒 ~1 min 🎯 5 questions

Official statement

Canonical tag elements are not considered when they are dynamically generated by JavaScript. Make sure the static HTML version correctly sends the canonical tag.
9:40
🎥 Source video

Extracted from a Google Search Central video

⏱ 56:37 💬 EN 📅 15/05/2018 ✂ 14 statements
Watch on YouTube (9:40) →
Other statements from this video 13
  1. 2:06 Google fusionne-t-il vraiment les pages similaires en une seule version indexée ?
  2. 4:34 Le pré-rendu basé sur l'user-agent est-il devenu la seule méthode recommandée par Google ?
  3. 5:49 Faut-il vraiment adapter la longueur de ses meta descriptions aux snippets Google ?
  4. 7:53 Faut-il bloquer la redirection automatique vers l'app mobile pour préserver son SEO ?
  5. 7:53 Les redirections furtives vers les applications mobiles sont-elles un frein au référencement ?
  6. 8:32 Google propose-t-il vraiment une révision manuelle SEO de votre site ?
  7. 11:17 Les PWA sont-elles vraiment indispensables pour le référencement naturel ?
  8. 16:56 Faut-il corriger les URLs marquées 'submitted URL not selected as canonical' ?
  9. 17:36 Faut-il supprimer un sitemap qui contient trop d'erreurs ?
  10. 19:40 Comment Google distingue-t-il réellement le contenu dupliqué des adresses identiques ?
  11. 25:43 Faut-il vraiment rediriger toutes les pages HTTP vers HTTPS pour éviter les problèmes d'indexation ?
  12. 37:33 Faut-il craindre de trop lier vers Wikipédia ou des sites d'autorité ?
  13. 42:06 Pourquoi les URL avec dièse (#) bloquent-elles l'indexation de vos pages Angular ?
📅
Official statement from (7 years ago)
TL;DR

Google completely ignores canonical tags that are dynamically generated via JavaScript. Only the static HTML version counts for determining a page's canonical URL. For sites using AngularJS or any other JavaScript framework, this means your rel=canonical must be present in the initial HTML source code, before any script execution. Otherwise, Google will choose the canonical version on its own—and that choice may differ from your intention.

What you need to understand

Why does Google distinguish between static HTML and JavaScript?

Googlebot executes JavaScript, that's been established for years. But the execution occurs in two distinct phases. First, the crawl retrieves the raw HTML sent by the server. Then—sometimes with a delay of several hours or days—comes rendering, where scripts modify the DOM.

The canonical tag serves to disambiguate URLs right from the crawl phase. If it only appears after JavaScript execution, it arrives too late in the pipeline. Google has already made its indexing decision based on the initial HTML. That's why Mueller insists on the term "static": the signal must be immediately available, without depending on a rendering thread.

What does this mean for JavaScript frameworks?

AngularJS—and by extension Angular, React, Vue—often generate the entire client-side content. If your application injects the canonical tag via JavaScript, the source HTML does not contain it. The server sends an empty skeleton, and the framework builds the page afterward.

So Google sees a page without a canonical tag in the initial HTML. It doesn't matter if the script correctly adds the tag 200 milliseconds later: the signal is not taken into account. As a result, Google determines for itself which URL it considers canonical, and that could be a version with parameters, a mobile variant, or any other URL it finds relevant.

Does this rule apply to all elements on the page?

No, and that's crucial. Google perfectly indexes content generated in JavaScript: titles, texts, internal links. But some technical signals—canonical, hreflang, certain metadata—must be present in the static HTML to be reliable.

The reason? These tags influence decisions made before rendering: choice of the version to index, crawl budget, page clustering. If Google has to wait for rendering to detect them, it may make contradictory decisions between the crawl and rendering phases. To avoid this conflict, it simply ignores signals arriving too late.

  • JavaScript canonicals are not taken into account by Googlebot, regardless of the rendering quality
  • Static HTML sent by the server (before JS execution) is the only reliable source for the canonical tag
  • Client-side frameworks (AngularJS, React, Vue) require server-side rendering (SSR) or static site generation (SSG) to send valid canonicals
  • Other affected technical signals: hreflang, certain meta tags, certain link attributes (nofollow may differ)
  • Textual content itself can be generated in JavaScript and will be correctly indexed after rendering

SEO Expert opinion

Does this statement reflect on-the-ground observations?

Yes, and it's confirmed by repeated tests. I've seen dozens of sites in React or Vue where the canonical was correct in the final DOM (visible in the browser inspector), but Google indexed another version. The Search Console displayed "Alternative URL with appropriate canonical tag" even though the canonical pointed correctly to itself.

The diagnosis? A curl of the page showed an empty <head>. The canonical only existed on the client-side. Google was making its indexing decision based on the raw HTML, completely ignoring the JavaScript tag, and picking a different URL—often one with UTM parameters or a paginated variant.

Why can't Google just wait for rendering?

It's a question of latency and consistency. The crawl is nearly instantaneous: Googlebot fetches the HTML in a few hundred milliseconds. Rendering can take several seconds, or even be delayed for hours if the crawl budget is tight.

If Google had to wait for rendering to know the canonical of each page, it would need to store provisional decisions and then revise them after rendering. This would create massive inconsistencies: a URL would first be considered canonical and then replaced by another. Ranking signals (backlinks, age) would be diluted among several temporary versions. Google has decided: technical signals must be immediate and stable.

Are there exceptions or nuances to this rule?

Let's be honest: [To be verified] Google has never published an exhaustive list of elements ignored in JavaScript. Mueller speaks specifically of canonicals, but on-the-ground observations suggest that hreflang is in the same case. Meta robots tags (noindex, nofollow) seem to be taken into account even in JavaScript, but sometimes with a problematic delay.

The important nuance: if your site uses dynamic rendering (serving different HTML to bots vs users), Google can detect the canonical in the version served to bots. But Google officially discourages this practice—it smells like cloaking. The clean solution remains Server-Side Rendering (SSR) or static pre-generation (SSG), where the HTML sent to everyone already contains the canonical.

Warning: Do not confuse "Google does not index JavaScript content" (false since 2015) with "Google ignores certain technical signals in JavaScript" (true). Textual content, links, images generated in JS are perfectly indexed. Only certain elements in the <head> require server-side sending.

Practical impact and recommendations

How can I check that my canonical is static?

The simplest method: curl or the browser's "View Source" tool (right-click > View Page Source, not the inspector). If the <link rel="canonical"> tag appears in this raw code, it is static. If it only appears in the DOM inspector after full loading, it is generated in JavaScript—therefore ignored by Google.

Another reliable tool: Google Search Console > URL Inspection > "HTML Sent" tab. This view shows exactly what Googlebot received before rendering. If your canonical is not there, it’s a failure. You can also use Google's Mobile-Friendly Test or Rich Results Test, which display the raw HTML before JavaScript execution.

What technical solutions are available for a JavaScript site?

Server-Side Rendering (SSR) is the most reliable solution. Next.js for React, Nuxt for Vue, Angular Universal for Angular: these frameworks generate the complete HTML on the server before sending. The canonical is already present in the initial HTTP response. Googlebot and users receive the same enriched HTML.

Alternative: Static Site Generation (SSG). Gatsby, Next.js in export mode, Nuxt generate pre-compile all pages into static HTML at build time. Each page is a complete HTML file with its canonical. Perfect for sites with little content change. For very dynamic sites, SSR remains preferable—or a hybrid (SSG for stable pages, SSR for user pages).

What if I can't migrate to SSR right away?

Temporary solution: pre-rendering via a service like Prerender.io or Rendertron. The server detects bots (Googlebot user-agent) and serves a pre-rendered HTML version, while users receive the classic SPA. This is technically cloaking, but Google tolerates this practice if both versions display the same content.

Another option: inject the canonical on the server in the initial <head>, even if the rest of the page is managed in JavaScript. Many frameworks allow you to template the base HTML with server variables. You can thus dynamically insert the correct canonical before sending, without overhauling your whole architecture. For such technical optimizations—especially on complex stacks—working with a specialized SEO agency can avoid months of trial and error and secure your migration.

  • Check for the presence of the canonical in the raw source HTML (curl or "View Source")
  • Use Google Search Console > URL Inspection to confirm that Google sees the canonical correctly
  • Migrate to SSR (Next.js, Nuxt, Angular Universal) or SSG (Gatsby, Next export) if possible
  • If migration is not immediately possible: pre-rendering for bots or server-injection of the canonical in the initial <head>
  • Also audit hreflang, meta robots, and other potentially JavaScript-generated technical signals
  • Test changes with Google's Mobile-Friendly Test and Rich Results Test before deployment
The rule is simple: any canonical tag generated solely in JavaScript is invisible to Google. The static HTML sent by the server must contain the complete canonical. For sites using modern JavaScript frameworks, this requires either Server-Side Rendering, static pre-generation, or a server-side injection of the tag before sending. Always check the raw HTML received by Googlebot, and do not rely solely on your browser's DOM inspector—this shows the final state after JavaScript, not what Google sees during the crawl phase.

❓ Frequently Asked Questions

Est-ce que Google indexe quand même mon contenu si la canonical est en JavaScript ?
Oui, Google indexera le contenu textuel généré en JavaScript après rendering. Mais il ignorera la balise canonical JavaScript et choisira lui-même l'URL canonique, ce qui peut causer des problèmes de duplication ou d'indexation de mauvaises versions.
Les hreflang sont-elles aussi concernées par cette limitation ?
Très probablement oui, bien que Google ne l'ait pas confirmé aussi explicitement que pour les canonicals. Les observations terrain montrent que les hreflang générées en JavaScript sont souvent ignorées. Privilégiez toujours le HTML statique ou les HTTP headers pour les hreflang.
Le Server-Side Rendering ralentit-il mon site ?
Pas nécessairement. Le SSR ajoute une latence serveur (quelques dizaines de millisecondes), mais élimine le délai de rendering côté client. Résultat : le First Contentful Paint est souvent meilleur. Avec du cache serveur et un CDN, les performances restent excellentes.
Puis-je utiliser une balise canonical HTTP header au lieu du HTML ?
Oui, Google supporte les canonicals envoyées via HTTP header (Link: <url>; rel="canonical"). C'est même une solution élégante pour les sites JavaScript : le serveur peut injecter le header sans toucher au HTML. Testez bien que Google la détecte dans la Search Console.
Que se passe-t-il si j'ai à la fois une canonical statique et une JavaScript différente ?
Google prendra en compte la canonical statique et ignorera celle en JavaScript. Si les deux pointent vers des URLs différentes, seule la version HTML initiale sera respectée. Évitez cette situation : elle crée de la confusion et des signaux contradictoires.
🏷 Related Topics
Content Crawl & Indexing JavaScript & Technical SEO

🎥 From the same video 13

Other SEO insights extracted from this same Google Search Central video · duration 56 min · published on 15/05/2018

🎥 Watch the full video on YouTube →

Related statements

💬 Comments (0)

Be the first to comment.

2000 characters remaining
🔔

Get real-time analysis of the latest Google SEO declarations

Be the first to know every time a new official Google statement drops — with full expert analysis.

No spam. Unsubscribe in one click.