SPA SEO-friendly avec Vue.js : conseils, outils et exemple de prerender
Amine Lahmary·Aug 2, 2026·6 min read
Pourquoi les SPA ont du mal avec le SEO
Une application monopage (SPA) affiche son contenu avec JavaScript après le chargement de la page. Le serveur n'envoie qu'une petite coquille HTML. Quand Google visite :
- Le robot lit le HTML brut — une coquille vide.
- Ensuite, Google exécute le JavaScript dans une deuxième vague, plus lente.
- Certaines pages ne sont jamais entièrement rendues ni indexées. Cela signifie que les titres, descriptions et contenus sont invisibles au premier abord. La solution est simple : donnez aux robots du vrai HTML dès le départ.
Les outils dont vous avez besoin pour le SEO Vue
Voici les meilleurs outils pour le SEO Vue.js en 2026. Vous n'en avez pas besoin de tous — commencez par ceux qui résolvent votre plus gros problème.
OutilRôleQuand l'utiliser@unhead/vueGère les balises title et meta par pageChaque SPAvue-routerRoutage côté client avec des URL propresChaque SPAvite-plugin-sitemapGénère sitemap.xml à la compilationRoutes statiquesScript de prerender PuppeteerRendu du HTML complet à la compilationPages de contenurobots.txtDit aux robots quoi explorerChaque siteJSON-LDDonnées structurées pour les résultats richesPages clés
Regardons chacun d'entre eux.
1. @unhead/vue pour les balises meta dynamiques
Chaque page a besoin de son propre title et de sa propre description. @unhead/vue est le standard moderne pour Vue 3. Il remplace l'ancien vue-meta.
<script setup>
import { useHead } from '@unhead/vue'
useHead({
title: 'À propos | Amine Lahmary',
meta: [{ name: 'description', content: 'Développeur Vue.js freelance à Marrakech.' }]
})
</script>
Utilisez des valeurs computed pour que les balises se mettent à jour quand vos données arrivent de l'API.
2. Des URL propres avec vue-router
Utilisez des URL propres et descriptives. De bonnes URL aident Google et les humains à comprendre vos pages.
/blog/mon-premier-projet-vue → bien
/?page=blog&post=123 → mal
Ajoutez une route 404 générique pour que les pages manquantes se comportent correctement.
3. vite-plugin-sitemap
Un sitemap liste chaque page que vous voulez indexer. vite-plugin-sitemap le crée pour vous pendant vite build. Ajoutez vos routes statiques dans dynamicRoutes :
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Sitemap from 'vite-plugin-sitemap'
export default defineConfig({
plugins: [
vue(),
Sitemap({
hostname: 'https://www.votre-site.dev',
dynamicRoutes: ['/about', '/contact', '/my-work', '/blog']
})
]
})
4. robots.txt
Placez robots.txt dans le dossier public/. Vite le copie automatiquement dans le build.
User-agent: *
Allow: /
Sitemap: https://www.votre-site.dev/sitemap.xml
5. Les données structurées JSON-LD
JSON-LD dit à Google exactement ce que contient votre page. Ajoutez-le avec useHead :
useHead({
script: [
{
type: 'application/ld+json',
children: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: 'SPA SEO-friendly avec Vue.js',
author: { '@type': 'Person', name: 'Amine Lahmary' },
datePublished: '2026-08-02'
})
}
]
})
La checklist SEO pour Vue.js
Suivez ces conseils pour rendre n'importe quelle SPA Vue SEO-friendly :
- Remplissez le
index.htmlpar défaut. C'est ce que les robots lisent en premier. Donnez-lui un vrai title, une description et des balises Open Graph. - Définissez une URL canonique sur chaque page. Elle dit à Google quelle version d'une URL est officielle.
- Mettez à jour les balises meta par route. Utilisez
useHead()avec des valeurs réactives. - Ajoutez un sitemap. Soumettez-le dans Google Search Console.
- Bloquez les pages privées. Utilisez
noindexsur les tableaux de bord et les zones d'administration. - Ne bloquez pas JavaScript. Ne bloquez jamais
.jsni.csspour Googlebot dansrobots.txt. - Gérez les 404. Ajoutez un fallback serveur pour que les liens profonds fonctionnent et renvoient un vrai 404.
- Utilisez du HTML sémantique. Des titres en ordre (
h1,h2,h3) aident les moteurs à comprendre votre contenu.Exemple de prerender : du HTML complet à la compilation
Le prerendering est le moyen le plus simple de donner aux robots du vrai HTML sans passer à un framework serveur. Voici comment ça marche : au moment du build, un navigateur headless visite chaque route, attend que Vue rende la page, puis enregistre le HTML final. Quand Google visite plus tard, il lit des pages complètes et indexables.
C'est exactement l'approche utilisée par ce site. Voici un exemple fonctionnel.
Étape 1 : Déclenchez un événement « prêt » dans votre application Vue
Dans votre composant de page ou de blog, prévenez le script de prerender quand le contenu est prêt :
<script setup>
import { onMounted } from 'vue'
import { useBlog } from '@/composables/useBlog'
const { post, fetchPost } = useBlog()
onMounted(async () => {
await fetchPost(route.params.slug)
document.dispatchEvent(new Event('prerender-ready'))
})
</script>
Étape 2 : Écrivez le script de prerender
Créez scripts/prerender.js. Il utilise Puppeteer pour capturer chaque route :
import puppeteer from 'puppeteer'
import { promises as fs } from 'node:fs'
import path from 'node:path'
const DIST = path.resolve('dist')
const routes = ['/blog', '/about', '/contact', '/my-work']
const browser = await puppeteer.launch({ headless: true })
for (const route of routes) {
const page = await browser.newPage()
await page.goto(`http://localhost:5173${route}`, {
waitUntil: 'networkidle0'
})
await page.evaluate(() => {
return new Promise((resolve) => {
if (document.readyState === 'complete') resolve()
document.addEventListener('prerender-ready', resolve, { once: true })
})
})
const html = await page.content()
const outputDir = path.join(DIST, route === '/' ? '' : route)
await fs.mkdir(outputDir, { recursive: true })
await fs.writeFile(path.join(outputDir, 'index.html'), html)
console.log(`Prerendu : ${route}`)
}
await browser.close()
Étape 3 : Lancez-le après le build
Ajoutez l'étape de prerender à vos scripts :
{
"scripts": {
"build": "vite build",
"prerender": "node scripts/prerender.js",
"postbuild": "prerender"
}
}
Le résultat est un dossier dist/ avec de vrais fichiers HTML :
dist/
├── index.html
├── about/index.html
├── contact/index.html
├── my-work/index.html
└── blog/index.html
Les moteurs de recherche et les aperçus sur les réseaux sociaux lisent ces fichiers instantanément. Les utilisateurs gardent l'expérience SPA rapide.
Prerender ou SSR : que choisir pour Vue ?
PrerenderingSSR (Nuxt)ConfigurationPetit script de buildGros changement de frameworkServeur nécessaireNon, fichiers statiquesOui, serveur NodeIdéal pourContenu qui change rarementPages temps réel, spécifiques à l'utilisateurVitesseTrès rapidePlus lent par requête
Choisissez le prerendering quand vos pages sont surtout statiques — articles de blog, pages d'atterrissage, portfolio. Choisissez le SSR quand chaque requête doit afficher des données fraîches et personnalisées.
Derniers conseils pour une SPA Vue.js SEO-friendly
- Commencez par la checklist. La plupart des applications Vue gagnent 80 % de leur SEO grâce à de bonnes balises meta, un sitemap et un
index.htmlcorrect. - Ajoutez le prerendering quand vous avez beaucoup de pages de contenu à faire classer.
- Gardez une seule source de vérité pour les routes — utilisez la même liste pour votre sitemap et votre script de prerender afin de ne rien manquer.
- Vérifiez votre sortie : après le build, ouvrez un fichier HTML prerendu et confirmez que le title, la description et le contenu sont là. Les SPA Vue.js peuvent parfaitement bien se classer dans Google. Avec les bons outils et un petit script de prerender, votre application sera trouvée — et votre contenu sera enfin vu.
Cet article a été écrit en août 2026. Les outils de prerendering et de SEO évoluent vite, vérifiez toujours la documentation la plus récente de @unhead/vue et vite-plugin-sitemap.