Guide Vue SEO
Vue 3 defaults to rendu côté client, so le contenu isn't in the raw HTML. Ce is how to faire Vue apps crawlable and indexable — router mode, @unhead/vue, prerendering with vite-ssg, SSR/SSG with Nuxt, hydration, and Core Web Vitals.
Langues
Vue 3 defaults to rendu côté client, so a plain Vite + Vue app ships an vide HTML shell and builds lune page in le navigateur. Google peut render it — but rendering is delayed and async données peut be missed, and Bing and social scrapers souvent can't run the JS at tout. The fixes: utiliser Vue Router history mode (pas hash mode), manage <head> with @unhead/vue, and put content in the HTML with prerendering (vite-ssg), SSR, or SSG via Nuxt. Dynamic rendering is deprecated — don't construire on it.
TL;DR — Vue builds votre page in le navigateur by par défaut. Que signifie the raw HTML a moteur de recherche premier downloads is nearly vide — the contenu réel seulement montre up après JavaScript runs. Google peut usually handle ce, but Bing and the bots que faire social-share previews souvent can’t. The fixes: utiliser Vue Router’s “history” mode pour clean URLs, ajouter a petit library appelé
@unhead/vuepour votre titles and descriptions, and pour pages que besoin to rank, construire the HTML ahead of temps (prerendering or Nuxt) au lieu de seulement in le navigateur.
Pourquoi Vue nécessite special SEO attention
Quand vous construire a site with Vue 3 the normal façon (Vite + Vue), le serveur sends a tiny HTML fichier — basically an vide container — and a big JavaScript bundle. The navigateur runs que JavaScript to draw the réel page. Ce is appelé client-side rendering (CSR). Evidence for this claim A Vue application can render its interface in the browser with client-side JavaScript. Scope: Vue client-side rendering architecture. Confidence: high · Verified: Vue: SSR guide
A human jamais notices. A moteur de recherche pourrait. The premier chose a robot d’exploration downloads is que nearly-empty container. It has to run votre JavaScript to voir anything — and pas every robot d’exploration fait que bien.
- Google runs an up-to-date version of Chrome and peut render votre Vue app. But it fait the rendering plus tard, in a queue, and si votre content waits on a slow datune requête, Google peut déplacer on avant it loads.
- Bing, DuckDuckGo, and social-preview bots (the ones que faire the little card quand vous paste a lien into X, Slack, or iMessage) are beaucoup moins reliable at running JavaScript. On a plain Vue app, votre social previews peut come up blank.
The three choses to obtenir correct
-
Utiliser “history” mode in Vue Router, pas “hash” mode. Hash-mode URLs regarder comme
example.com/#/about. Vue Router’s propre docs dire hash mode “has a bad impact in SEO.” UtilisercreateWebHistory()so votre URLs regarder commeexample.com/about. Evidence for this claim Vue Router recommends HTML5 history mode for normal-looking URLs and warns that hash mode has a negative SEO effect. Scope: Vue Router history modes. Confidence: high · Verified: Vue Router: History modes -
Manage votre titles and meta tags with
@unhead/vue. Out of the box, every Vue page shares the même title and description.@unhead/vuelets chaque page définir its propre — notamment the Ouvrir Graph and Twitter tags que drive social previews. -
Put votre content in the HTML pour pages que besoin to rank. Au lieu de building everything in le navigateur, construire it ahead of temps so le contenu is déjà là quand a robot d’exploration arrives. The facile on-ramp is prerendering with a outil appelé
vite-ssg. Pour bigger or plus dynamic sites, Nuxt (the official Vue framework pour ce) fait it pour vous.
Devrait vous simplement utiliser Nuxt?
Pour la plupart sites où SEO en réalité matters, yes — and Vue’s propre documentation points
vous là. Nuxt handles the rendering, the meta tags, sitemaps, and robots.txt pour
vous. Si votre site is fairly static (a marketing site, docs, a blog), vite-ssg is
a lighter option que doesn’t exiger switching frameworks.
Vouloir the deeper version — how Google’s render queue fonctionne, the @unhead/vue code,
prerendering vs. SSR, hydration mismatches, and Core Web Vitals? Switch to the
Avancé tab.
TL;DR — Vue 3 is CSR by par défaut, so le contenu isn’t in the raw HTML — Google renders it plus tard via its evergreen Chromium WRS, but the render is queued and async données récupéré in
onMountedpeut be missed, and Bing/social scrapers souvent don’t run the JS at tout. Non-negotiables: Vue RoutercreateWebHistory()(hash mode has “a bad impact in SEO”),<head>via@unhead/vue/useSeoMeta(), and a rendering strategy que obtient content into HTML —vite-ssgprerendering pour content-stable sites, Nuxt pour complet SSR/SSG. Dynamic rendering is deprecated;prerender-spa-pluginis legacy. Watch hydration mismatches (a server/client content delta is an SEO problem, pas simplement a perf un) and the CSR bundle’s hit on LCP. Pour the framework-agnostic version of tout of ce, voir JavaScript SEO.
The par défaut Vite + Vue scaffold is client-side rendered
A plain npm create vue@latest app (Vite + Vue) ships a near-empty HTML shell and
a JavaScript bundle. Le navigateur executes que bundle to construire the DOM. Ce is
fine pour utilisateurs and a problem pour robots d’exploration: the raw HTML contient almost aucun
content, and everything dépend on rendering.
That’s a property of the par défaut scaffold, pas a ceiling on Vue itself — Vue core
aussi supports server rendering (createSSRApp) and static generation as
first-class paths, and Vue’s propre SSR guide steers la plupart production SSR/SSG fonctionner
toward Nuxt plutôt que a hand-rolled setup. So avant reaching pour a fix, vérifier
ce que votre app is en réalité shipping: a bare Vite SPA with aucun rendering config is
CSR; the même app behind Nuxt or vite-ssg isn’t.
Vue’s propre SSR guide is direct à propos de the upside of pas doing ce: with rendu côté serveur, “the moteur de recherche robots d’exploration va directement voir the entièrement rendered page.” The flip side is ce que vous ship by par défaut — content que seulement exists après JavaScript runs. Evidence for this claim Vue server-side rendering sends rendered HTML so crawlers can directly see page content. Scope: Vue SSR benefits; does not guarantee indexing. Confidence: high · Verified: Vue: SSR guide
(Vue 2 reached fin of life in December 2023; everything ici is Vue 3.)
How Googlebot handles a Vue app
Google processes JavaScript in phases — explorer the raw HTML, alors render it in an evergreen, headless Chromium instance (the Web Rendering Service), alors index the rendered result. Two choses follow from que:
- Rendering is queued and delayed. Une page sits in the render queue — usually seconds to minutes, but it peut spike. Content que exists seulement après JS runs is pas immédiatement indexable; content in the raw HTML is.
- Async données is the réel risk. Synchronous JavaScript renders reliably. Données
récupéré from an API après mount n’est pas guaranteed to be caught. Vue’s SSR guide
dit it plainly: “Si votre app starts with a chargement spinner, alors récupère content
via Ajax, the robot d’exploration ne va pas wait pour vous to finish. Ce signifie si vous have
content récupéré asynchronously on pages où SEO is important, SSR pourrait be
necessary.” Practically: données récupéré in
onMountedis client-only and invisible to robots d’exploration que don’t render — and at risk même with the ones que do.
John Mueller has décrit the échec mode pour SPA-style setups où the static HTML is mostly identical and tout the unique content dépend on JavaScript: si que JS can’t be executed correctement, lune pages fin up looking the même to Google, and the focus stays on the boilerplate HTML plutôt que the JS-loaded content. The lesson is the même as the broader JavaScript SEO page: obtenir le contenu into the DOM, fast and reliably.
Bing and social bots are worse at ce que Google. Bing has aucun rendering pipeline comparable to Google’s, and social preview scrapers (X, Slack, iMessage) généralement don’t run JavaScript at tout — so a bare CSR Vue app produces vide share previews. Si Bing trafic or social sharing matters, prerendering or SSR isn’t optional.
Vue Router: utiliser createWebHistory(), pas hash mode
Vue Router has two history modes. Hash mode (createWebHashHistory()) produces
URLs comme example.com/#/about; Vue Router’s docs dire it “fait cependant have a bad
impact in SEO” parce que everything après the # is a fragment le serveur ignores. Evidence for this claim Vue Router hash history uses a URL fragment that is not sent to the server and is discouraged for SEO. Scope: Vue Router hash history. Confidence: high · Verified: Vue Router: History modes
Utiliser HTML5 history mode:
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [/* ... */],
})History mode donne clean URLs (example.com/about) but exige a server
fallback — quelconque direct requête to a route has to serve index.html so Vue peut
prendre over, sinon direct hits 404. Configurer que catch-all on votre host (Nginx
try_files, an SPA rewrite on Netlify/Vercel/Cloudflare, etc.).
Scope que rewrite carefully — a catch-all that’s aussi broad aussi sert
index.html pour manquant static assets, réel API routes, or pages vous en réalité
vouloir to 404. Que silently undoes the soft-404 guidance ci-dessous and peut hide a
broken lien behind une page que semble comme it “worked.”
Pour genuine not-found states, éviter soft-404s — a client-side “not found” view que
encore renvoie 200 peut obtenir indexé as an vide shell. Google’s guidance is to
soit redirection to une URL que renvoie a réel 404 status or ajouter a
<meta name="robots" content="noindex"> to error pages, and to utiliser the History API
pour routing entre views.
Head and meta management: @unhead/vue
By par défaut every Vue route shares un <title> and un meta description. The tag
history ici matters parce que the old réponses are dead ends:
vue-meta— the Nuxt 2-era library. Legacy.@vueuse/head— its successor, now sunset.@unhead/vue— the current community standard, and ce que vous devez utiliser pour a non-Nuxt Vue 3 app.
The ergonomic entry point is the useSeoMeta() composable — type-safe, XSS-safe,
and aware of 100+ meta tags notamment Ouvrir Graph and Twitter Card:
import { useSeoMeta } from '@unhead/vue'
useSeoMeta({
title: 'Vue SEO Guide',
description: 'How to make a Vue 3 app crawlable and indexable.',
ogTitle: 'Vue SEO Guide',
ogDescription: 'How to make a Vue 3 app crawlable and indexable.',
twitterCard: 'summary_large_image',
})Meta peut be reactive — réussir a getter or computed valeur and the tags mettre à jour quand votre données fait. Pour balise canonicals, the safest pattern is encore HTML, pas JS: Google’s guidance is que “the best way to set the canonical URL is to use HTML,” and si vous doit inject it with JavaScript, toujours définir it to the même valeur the HTML voudrait. (I testé JS canonicals at Ahrefs and trouvé Google fait respect les — it même led Google to ajouter an exception to its docs — but HTML is encore the lower-risk chemin.)
Pick a rendering strategy
Ce is the decision que en réalité moves the needle. Même menu as the framework- agnostic JavaScript SEO page, applied to Vue.
Rendu côté client (CSR) — the par défaut, and the risky un. Acceptable pour app-like pages behind a login, dashboards, and anything vous don’t besoin indexé. Pas acceptable pour content que doit rank or be shared.
Prerendering with vite-ssg. Pour content-stable Vue 3 SPAs, vite-ssg
generates static HTML at construire temps — swap votre construire script from vite build to
vite-ssg build. It ships @unhead/vue construit in. Great pour marketing sites, docs,
and blogs; pas a substitute pour SSR on highly dynamic, per-request pages. Remarque que
the old webpack-era prerender-spa-plugin is legacy and effectively
unmaintained — vite-ssg (or Nuxt) is the modern replacement.
Rendu côté serveur. Vue’s official guide covers a manual SSR setup with
@vue/server-renderer, but it explicitly steers la plupart projects to a meta-framework
plutôt que rolling votre propre — and pour simple cas it même dit “si you’re seulement
investigating SSR to améliorer the SEO of a handful of marketing pages … alors vous
probably vouloir SSG au lieu de SSR.” Si vous do roll manual SSR, créer the app,
router, and store fresh per requête: on a long-running Node server, module-level
singletons obtenir reused à travers requêtes, and mutating shared state with un user’s
données peut leak it into un autre user’s réponse. That’s un plus raison Vue’s docs
point la plupart projects at Nuxt, qui handles per-request isolation pour vous.
Nuxt — the recommended complet solution. Nuxt donne vous SSR and SSG out of the
box, built-in useSeoMeta() and head management, and the @nuxtjs/seo module pour
sitemaps, robots.txt, and données structurées. Pour la plupart Vue projects où SEO matters,
ce is the chemin Vue’s propre docs point to. (Nuxt has its propre depth — covered
separately; treat ce as the cross-link, pas the deep dive.)
Dynamic rendering — don’t. Serving prerendered HTML to bots and the SPA to utilisateurs was toujours a workaround, and Google deprecated it in 2024, removing the implementation docs. Construire on SSR or SSG à la place.
Pour documentation specifically, VitePress is the Vue-native static site
generator. Every page ships as plain HTML — aucun JS rendering barrier — and SEO is
configuré via frontmatter (title, description, head) or the transformHead
construire hook pour canonical/dynamic tags.
Hydration mismatches are an SEO problem, pas simplement a perf un
Quand vous do SSR/SSG, the client mounts with createSSRApp() — pas the plain
createApp() — and hydrates le serveur-rendered HTML au lieu de rebuilding it
from scratch. Si le serveur HTML and the client render diverge, Vue discards and
re-renders the mismatched nodes. In SEO terms, que signifie le contenu Google indexé
from le serveur render peut differ from ce que the utilisateur sees après hydration — a
quality-signal inconsistency, pas simplement a flicker. Courant causes: invalid HTML
nesting, random valeurs in templates, and date/temps discrepancies entre server and
client. Vue 3,5+ adds data-allow-mismatch to suppress the mismatch warning
selectively où a difference is intentional — it quiets the console, it doesn’t
faire le serveur and client output equivalent, so don’t reach pour it simplement to silence
a mismatch vous haven’t en réalité diagnosed.
Core Web Vitals are a Vue-specific concern
Par défaut CSR Vue ships a grand JS bundle que has to download, parse, and execute avant the largest content paints — so LCP suffers si vous ne faites pashing. Levers:
- Code splitting (Vite’s par défaut) and lazy-loaded routes so vous don’t ship the whole app up front.
fetchpriority="high"on the LCP hero image.- Vapor Mode — an opt-in compiler mode que bypasses the virtual DOM pour eligible components, qui peut cut hydration cost on SSR pages. It’s Vue 3,6, pas 3,5 — encore experimental (beta/release-candidate as of mid-2026, pas yet in the stable 3,5.x line) — worth watching, pas something to depend on in production today.
Données structurées in Vue
Google executes JavaScript avant reading données structurées, so injecting JSON-LD
fonctionne — @unhead/vue’s useHead() with a script of type
application/ld+json is the reliable pattern. Parce que it dépend on rendering,
confirmer it with Inspection d’URL plutôt que assuming Google saw it.
Où ce fits
Vue SEO is un instance of the general JavaScript SEO problem — parity, interaction, state, timing — and it shares almost everything with the CMS headless situation, où the rendering mode of the frontend decides the outcome.
Un caveat que s’applique to every option ci-dessus: SSR and SSG obtenir votre content into the HTML, but neither guarantees indexation, rankings, Core Web Vitals, or que hydration va match le serveur output exactly. Ils supprimer the JavaScript-rendering barrier — the rest of SEO (and correctness) is encore on vous.
Si vous remember un chose: obtenir votre content into the HTML. Everything sinon is detail.
AI summary
A condensed prendre on the Avancé version:
- The par défaut Vite + Vue scaffold is CSR — a plain
npm create vue@latestapp ships a near-empty HTML shell and builds the DOM in le navigateur. That’s a property of the bare scaffold, pas a ceiling on Vue itself — Vue core aussi supports SSR (createSSRApp) and SSG as first-class paths. - Google renders Vue, but with caveats — its evergreen Chromium WRS runs the JS,
but rendering is queued/delayed and async données (e.g. récupéré in
onMounted) peut be missed. Vue’s SSR docs: a robot d’exploration “will not wait for you to finish” an Ajax récupérer behind a spinner. - Bing and social scrapers are worse — ils souvent don’t run JS at tout, so a bare CSR Vue app produces vide share previews.
- Router: utiliser
createWebHistory(), pas hash mode (hash has “a bad impact in SEO”). History mode nécessite a serverindex.htmlfallback — scoped so it doesn’t aussi swallow réel static assets, API routes, or intended 404s. Éviter soft-404s. - Head/meta:
@unhead/vuewithuseSeoMeta()is the current standard;vue-metais legacy,@vueuse/headis sunset. Préférer HTML canonicals. - Rendering strategy decides it: CSR (risky, OK pour app pages) →
vite-ssgprerendering (content-stable sites) → SSR / SSG via Nuxt (the recommended complet solution).prerender-spa-pluginis legacy; dynamic rendering is deprecated. Si vous roll manual SSR, construire the app/router/store fresh per requête to éviter cross-request state leaks. - VitePress pour docs sites (plain static HTML).
- Hydration uses
createSSRApp(); mismatches créer a server/client content delta — an SEO quality problème, pas simplement a flicker. Vue 3,5+‘sdata-allow-mismatchsuppresses the warning pour intentional cas — it doesn’t faire the two renders equivalent. - Core Web Vitals: big CSR bundle hurts LCP — code-split, lazy routes,
fetchpriority="high", and (experimental, Vue 3,6 beta/RC — pas stable yet) Vapor Mode. - Données structurées via
@unhead/vueuseHead()JSON-LD; vérifier with URL Inspection. - Aucun option ici guarantees indexation, rankings, CWV, or hydration parity — SSR/SSG supprimer the JS-rendering barrier; the rest of SEO is encore on vous.
Documentation officielle
Primary-source documentation from Vue and the moteur de recherches.
Vue
- Rendu côté serveur (SSR) | Vue.js — the SEO benefit of SSR, the async/spinner caveat, and the SSG-for-marketing-pages recommendation.
- Différent History modes | Vue Router —
createWebHistory()vs. hash mode, the SEO remarque, and le serveur fallback requirement. - useSeoMeta() · Unhead — the current
@unhead/vuecomposable pour type-safe meta management. - Site Config | VitePress and Frontmatter Config | VitePress — SEO configuration pour Vue-powered docs sites.
- antfu-collective/vite-ssg | GitHub — build-time prerendering pour Vue 3 SPAs.
- Comprendre the JavaScript SEO basics — two-phase processing, the History API recommendation, soft-404 handling, and HTML canonicals.
- Dynamic Rendering as a workaround — now flagged as deprecated; SSR/static rendering/hydration recommended à la place.
- Introducing a nouveau JavaScript SEO video series — Google’s official JS SEO series (inclut the Vue.js episode).
Quotes from the source
On-the-record statements from Vue and Google. Chaque lien is a deep lien que jumps to the quoted passage on the source page.
Vue — SSR & SEO
- “Better SEO: the search engine crawlers will directly see the fully rendered page.” — Vue.js SSR guide. Jump to quote
- “As of now, Google and Bing can index synchronous JavaScript applications just fine. Synchronous being the key word there. If your app starts with a loading spinner, then fetches content via Ajax, the crawler will not wait for you to finish.” Jump to quote
- “If you’re only investigating SSR to improve the SEO of a handful of marketing pages … then you probably want SSG instead of SSR.” Jump to quote
Vue Router — history mode
- On hash mode: “It does however have a bad impact in SEO.” Jump to quote
Google — JavaScript SEO basics
- On canonicals: “The best way to set the canonical URL is to use HTML, but if you have to use JavaScript, make sure that you always set the canonical URL to the same value as the original HTML.” Jump to quote
Google — dynamic rendering (deprecated)
- “Dynamic rendering was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines.” Jump to quote
Vue SEO checklist
A réussir to confirmer a Vue 3 app is crawlable and indexable:
- Vue Router uses
createWebHistory()(HTML5 history mode), pascreateWebHashHistory(). - Server has an
index.htmlfallback so direct route hits don’t 404. -
@unhead/vueis wired up; every page sets its propre title, description, and canonical (pas tout sharing the par défaut). - Ouvrir Graph / Twitter Card tags are présent (and en réalité render pour social scrapers — i.e. they’re in the served HTML, pas CSR-only).
- Canonical is définir in HTML où possible; si injected via JS, it matches.
- SEO-critical content is in the HTML via SSR/SSG/prerender — pas récupéré in
onMountedon a CSR page. - Client-side not-found states retourner a réel
404or anoindex(aucun soft-404 shells). - JavaScript and CSS ne sont pas blocked in
robots.txt. - Aucun dynamic-rendering dependency in nouveau builds (deprecated by Google).
- Core Web Vitals réussir — code splitting, lazy routes,
fetchpriority="high"on the LCP image. - Si SSR/SSG: aucun hydration mismatches (vérifier the console; utiliser
data-allow-mismatchseulement pour intentional ones). - Données structurées (JSON-LD) confirmed in the rendered HTML via Inspection d’URL.
The mental models
1. The par défaut is the trap. Vue 3 out of the box is CSR — content isn’t in the raw HTML. Everything in Vue SEO is à propos de overriding que par défaut pour pages que besoin to be trouvé.
2. Rendering decides the outcome.
The unique highest-leverage choice is how the HTML is produced: CSR (risky) →
prerender/vite-ssg (content-stable) → SSR/SSG via Nuxt (dynamic, SEO-critical).
Pick the lightest option que puts votre content in the HTML.
3. Synchronous in the HTML, pas async après mount. Content that’s là synchronously renders reliably; données récupéré après mount may be missed — by the robots d’exploration que render late, and entirely by the ones que don’t.
4. Two audiences of bots. Google renders (eventually). Bing and social scrapers largely don’t. Design pour the worse un si Bing trafic or share previews matter — que signifie HTML, pas CSR.
5. The decision tree pour a nouveau Vue project.
Pure app behind a login? CSR is fine. Content-stable marketing/docs/blog? vite-ssg
or VitePress. Dynamic, per-request, SEO-critical content? Nuxt. Jamais reach pour
dynamic rendering or prerender-spa-plugin — les deux are dead ends in 2026.
6. Server and client doit agree. Hydration mismatch isn’t simplement a perf nit — it’s a content delta entre ce que Google indexé and ce que the utilisateur obtient. Garder the two renders identical.
Vue SEO — cheat sheet
Router mode
| Mode | URL | SEO |
|---|---|---|
createWebHistory() | example.com/about | Utiliser ce (nécessite server fallback) |
createWebHashHistory() | example.com/#/about | ”Bad impact in SEO” — éviter |
Head / meta libraries
| Library | Status |
|---|---|
vue-meta | Legacy (Nuxt 2 era) |
@vueuse/head | Sunset |
@unhead/vue (useSeoMeta()) | Current standard |
Rendering strategies
| Strategy | Quand | SEO risk |
|---|---|---|
| CSR (par défaut) | App pages, behind login | Highest |
vite-ssg prerender | Content-stable SPAs (marketing/docs/blog) | Low |
| SSR (Nuxt) | Dynamic, per-request pages | Low |
| SSG (Nuxt / VitePress) | Content connu at construire temps | Lowest |
prerender-spa-plugin | — | Legacy/unmaintained — don’t |
| Dynamic rendering | — | Deprecated by Google — don’t |
Fast facts
- Google renders Vue (evergreen Chromium WRS) — but delayed, and async données peut be missed.
- Bing + social scrapers souvent don’t run JS — bare CSR = vide share previews.
- Canonicals: HTML premier; JS canonicals fonctionner but are riskier.
- Vue 2 is EOL (Dec 2023) — Vue 3 seulement.
How devrait a Vue route render?
Choose a Vue SEO rendering path
Vue SEO mistakes
- Shipping search landing pages as a Vite SPA shell. Utiliser Nuxt SSR/SSG or prerendering so essential content is in source HTML.
- En utilisant hash mode pour public content routes. Fragments ne faites pas créer normal server URLs. Utiliser history routing with host fallback configuré correctement.
- Setting head tags seulement après client récupère. Generate metadata from server/construire données via the head integration.
- En utilisant dynamic rendering as the long-term fix. Maintain un consistent utilisateur/robot d’exploration rendering chemin au lieu de bot-specific output.
- Testing seulement with Google. Raw HTML matters to autre moteur de recherches, social scrapers, and outils que ne faites pas execute the application entièrement.
Raw HTML contient seulement the Vue mount element
Probable causer: the route is CSR-only. Fix: déplacer it to Nuxt SSR/SSG or prerender the finite route définir. Confirmer: curl renvoie the principal content and liens.
Direct route requêtes retourner 404
Probable causer: Vue Router history mode lacks server fallback or the deployment omitted generated routes. Fix: configurer host rewrites pour SPA-only routes or deploy réel SSR/static route output. Confirmer: refresh and direct requêtes retourner the intended status and page.
Titles mettre à jour in le navigateur but pas in source
Probable causer: metadata dépend on client lifecycle or an asynchronous navigateur récupérer. Fix: resolve données during SSR/SSG and render head tags with @unhead/vue or Nuxt’s head APIs. Confirmer: raw and rendered titles, canonicals, and robots directives agree.
Hydration replaces correct server content
Probable causer: server/client données or environment branches disagree. Fix: faire initial données deterministic and supprimer browser-only conditions from essential markup. Confirmer: hydration completes sans mismatch warnings or modification indexable content.
Comparer Vue raw and rendered output
curl -fsSL https://example.com/page/ > raw.html
grep -Eio '<title>[^<]+|<h1[^>]*>[^<]+|<link[^>]+rel="canonical"[^>]*' raw.htmlRun ce in DevTools Console après hydration:
({title: document.title, h1: document.querySelector('h1')?.textContent.trim(), canonical: document.querySelector('link[rel="canonical"]')?.href, links: [...document.querySelectorAll('a[href]')].length});Si the important valeurs exist seulement in the Console result, SSR/prerendering is incomplete.
Trouver hash-based content liens
[...document.querySelectorAll('a[href^="#"]')].map(a => ({text: a.textContent.trim(), href: a.getAttribute('href')}));Examiner the liste manually: in-page navigation is fine; en utilisant fragments as separate content routes is the problem.
Outils pour Vue SEO
- Inspection d’URL (Recherche Google Console) — the source of truth. Run a live tester and vérifier the rendered HTML, screenshot, page resources (was quelconque JS/CSS blocked?), and console messages. Ce is how vous confirmer votre Vue content, meta, and JSON-LD en réalité rendered.
- Résultats enrichis Tester — a fast rendered-HTML + structured-data vérifier pour a unique URL sans verifying le site.
- Chrome DevTools — diff View Source (raw HTML, ce que a non-rendering bot sees) contre the Elements panel (the hydrated DOM). The Console surfaces hydration mismatch warnings.
- Vue Devtools — inspect component state and router mode pendant que vous debug what’s client-only vs. server-rendered.
vite-ssg— build-time prerendering pour content-stable Vue 3 SPAs (swapvite build→vite-ssg build).- JavaScript-rendering robots d’exploration — Ahrefs Site Audit and Screaming Frog (JS-rendering mode) execute the JS so vous pouvez diff raw vs. rendered à travers the whole Vue site.
- Lighthouse / PageSpeed Insights — catch the CSR bundle’s hit on LCP and the Core Web Vitals levers (code splitting, lazy routes, image priority).
Testez vos connaissances: Vue SEO
Five rapide questions on making Vue apps crawlable and indexable. Pick an réponse pour chaque, alors vérifier.
Ressources utiles
My writing
- JavaScript SEO: A Definitive Guide — my complet guide to rendering, DOM parity, and the framework-level decisions; inclut the Vue Router history-vs-hash guidance and my JS-canonical tester.
- The Beginner’s Guide to SEO technique — où rendering and JavaScript SEO fit in the bigger picture.
My speaking
- How Search Fonctionne (SlideShare) — my walkthrough of exploration, rendering, indexation, and ranking. (My standing disclaimer s’applique: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From autour the industry
- Rendu côté serveur (SSR) | Vue.js — the official guide: SSR’s SEO benefit, the async caveat, and quand to pick SSG à la place.
- Différent History modes | Vue Router — pourquoi hash mode hurts SEO and how to configurer history mode.
- useSeoMeta() · Unhead — the current
@unhead/vuemeta API. - antfu-collective/vite-ssg | GitHub — build-time prerendering pour Vue 3 SPAs.
- Site Config | VitePress — SEO pour Vue-powered documentation sites.
- How Nuxt.js solves the SEO problems in Vue.js | LogRocket — the cas pour Nuxt as the SSR/SSG chemin.
- Google ne … plus recommends en utilisant dynamic rendering | Moteur de recherche Land — coverage of the dynamic-rendering deprecation.
- Vue.js And SEO: How To Optimize Reactive Websites | Smashing Magazine — a widely-cited 2019 piece; utile pour the async-timing experiments, but dated on tooling (pre-evergreen Chromium).
Videos
- SEO technique tips pour Vue.js by Martin Splitt (Recherche Google Central, 2019) — Google’s propre Vue-specific JavaScript SEO episode: making titles, descriptions, and URLs discoverable quand vous construire with Vue. Watch
- Recherche Google Central (YouTube) — Martin Splitt’s broader JavaScript SEO series covers rendering, the render queue, and the échec modes que appliquer to quelconque Vue app. Channel
Journal des modifications
Mis à jour le 18 juil. 2026.
Résumé éditorial et détails enregistrés des changements.Détails des changements
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
-
Les notes détaillées des changements sont actuellement disponibles en anglais.
Comparaison complète indisponible — aucun instantané antérieur n’a été archivé pour cette révision.