SEO et Balises Meta dans Nuxt 4 en 2026 : useHead, useSeoMeta et Questions d'Entretien

Guide complet sur les composables useHead et useSeoMeta de Nuxt 4. Optimisation SEO, Open Graph, Twitter Cards et questions techniques pour entretiens Vue.

SEO et Balises Meta dans Nuxt 4 en 2026 : useHead, useSeoMeta et Questions d'Entretien

Nuxt 4 propose deux composables pour gérer les balises meta SEO : useHead pour les éléments head généraux et useSeoMeta pour les métadonnées SEO typées. Avec la fin de vie de Nuxt 3 prévue le 31 juillet 2026, la maîtrise de ces composables dans Nuxt 4.5 devient indispensable pour tout développeur Vue préparant des entretiens techniques.

Différence Essentielle

useSeoMeta gère les balises spécifiques au SEO (title, description, Open Graph, Twitter Cards) avec un support TypeScript complet. useHead gère tout le reste : scripts, feuilles de style, URLs canoniques et balises meta personnalisées. Les deux composables fonctionnent ensemble pour une gestion complète du head.

useSeoMeta : Métadonnées SEO Typées dans Nuxt 4

Le composable useSeoMeta accepte un objet plat avec plus de 100 propriétés typées. Cette approche élimine les erreurs courantes comme la confusion entre les attributs name et property sur les balises Open Graph.

vue
<!-- pages/product/[id].vue -->
<script setup lang="ts">
const product = await useFetch(`/api/products/${route.params.id}`)

useSeoMeta({
  title: () => product.data.value?.name,
  description: () => product.data.value?.description,
  ogTitle: () => product.data.value?.name,
  ogDescription: () => product.data.value?.description,
  ogImage: () => product.data.value?.imageUrl,
  ogType: 'product',
  twitterCard: 'summary_large_image',
  twitterTitle: () => product.data.value?.name,
  twitterDescription: () => product.data.value?.description,
  twitterImage: () => product.data.value?.imageUrl,
})
</script>

La syntaxe avec fonction fléchée () => value crée des getters réactifs. Lorsque product.data change, les balises meta se mettent à jour automatiquement. Pour les pages statiques où les balises SEO ne changent jamais après le rendu initial, cette réactivité ajoute une surcharge inutile.

Balises Meta Côté Serveur Uniquement pour de Meilleures Performances

Les robots des moteurs de recherche et les bots IA comme GPTBot et ClaudeBot ne lisent que la réponse HTML initiale. Ils n'exécutent pas JavaScript. Les mises à jour des balises meta côté client leur sont donc invisibles.

vue
<!-- pages/about.vue -->
<script setup lang="ts">
if (import.meta.server) {
  useSeoMeta({
    title: 'À propos de SharpSkill',
    description: 'Plateforme de préparation aux entretiens techniques pour développeurs',
    ogTitle: 'À propos de SharpSkill',
    ogDescription: 'Plateforme de préparation aux entretiens techniques pour développeurs',
    ogImage: 'https://sharpskill.dev/og-about.png',
    robots: 'index, follow',
  })
}
</script>

Envelopper useSeoMeta dans import.meta.server garantit que le composable ne s'exécute que pendant le SSR. Les balises meta apparaissent dans le HTML envoyé aux robots, mais aucun watcher réactif n'est créé côté client. Cela réduit la taille du bundle et améliore les performances d'hydratation.

useHead pour Scripts, Liens et URLs Canoniques

Alors que useSeoMeta couvre les métadonnées SEO, useHead gère tout le reste : scripts externes, feuilles de style, URLs canoniques et attributs HTML/body.

vue
<!-- pages/blog/[slug].vue -->
<script setup lang="ts">
const route = useRoute()
const config = useRuntimeConfig()

useHead({
  link: [
    {
      rel: 'canonical',
      href: `${config.public.siteUrl}/blog/${route.params.slug}`,
    },
    {
      rel: 'alternate',
      hreflang: 'fr',
      href: `${config.public.siteUrl}/fr/blog/${route.params.slug}`,
    },
  ],
  script: [
    {
      type: 'application/ld+json',
      innerHTML: JSON.stringify({
        '@context': 'https://schema.org',
        '@type': 'Article',
        headline: article.value?.title,
        author: { '@type': 'Person', name: 'Anthony Fillion-Maillet' },
        datePublished: article.value?.publishedAt,
      }),
    },
  ],
})
</script>

Le tableau link gère les URLs canoniques et les balises hreflang pour l'internationalisation. Le tableau script injecte les données structurées pour les résultats enrichis. Les deux sont essentiels pour le SEO mais dépassent le cadre de useSeoMeta.

Prêt à réussir tes entretiens Vue.js / Nuxt.js ?

Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.

Hiérarchie des Balises Meta : Niveaux App, Layout et Page

Nuxt 4 fusionne les balises meta de trois niveaux : nuxt.config.ts (valeurs par défaut de l'app), layouts et pages. Les balises au niveau page surchargent celles du layout, qui surchargent celles de l'app.

nuxt.config.tstypescript
export default defineNuxtConfig({
  app: {
    head: {
      titleTemplate: '%s | SharpSkill',
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      ],
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      ],
    },
  },
})
vue
<!-- layouts/default.vue -->
<script setup lang="ts">
useSeoMeta({
  ogSiteName: 'SharpSkill',
  twitterSite: '@sharpskill',
})
</script>
vue
<!-- pages/index.vue -->
<script setup lang="ts">
useSeoMeta({
  title: 'Préparation aux Entretiens Techniques',
  description: 'Préparez votre prochain entretien technique avec des questions pratiques et des simulations',
})
</script>

Le titre final devient "Préparation aux Entretiens Techniques | SharpSkill" car la page fournit la valeur du placeholder %s et la config fournit le template. Cette hiérarchie évite la répétition tout en permettant des surcharges spécifiques à chaque page.

Questions Fréquentes d'Entretien sur le SEO Nuxt

Les entretiens techniques pour les postes Vue/Nuxt incluent souvent des questions sur le SSR et l'optimisation SEO. Voici les patterns attendus par les recruteurs.

Quand useSeoMeta doit-il utiliser des getters réactifs versus des valeurs statiques ?

Les valeurs statiques fonctionnent pour les pages au contenu fixe : pages d'accueil, pages à propos, pages légales. Les getters réactifs sont nécessaires quand les balises meta dépendent de données récupérées ou de paramètres de route. La différence de performance compte à grande échelle : 50 pages avec des watchers inutiles gaspillent de la mémoire et ralentissent l'hydratation.

Comment les robots IA diffèrent-ils de Googlebot ?

Googlebot exécute JavaScript et attend le rendu côté client. Les robots IA comme GPTBot et ClaudeBot récupèrent le HTML brut sans exécuter les scripts. Les balises meta rendues côté serveur atteignent les deux. Les balises uniquement côté client n'atteignent ni les bots IA ni les anciens moteurs de recherche.

Qu'est-ce qui casse le plus souvent les balises Open Graph ?

L'absence des dimensions de og:image. Facebook et LinkedIn mettent en cache les données OG de manière agressive. Quand les dimensions de l'image sont absentes, les plateformes peuvent afficher les miniatures incorrectement ou pas du tout.

vue
<script setup lang="ts">
useSeoMeta({
  ogImage: 'https://example.com/og-image.png',
  ogImageWidth: 1200,
  ogImageHeight: 630,
  ogImageAlt: 'Aperçu de l\'article montrant un éditeur de code avec syntaxe Vue',
})
</script>

Inclure ogImageWidth, ogImageHeight et ogImageAlt prévient les problèmes de rendu et améliore les scores d'accessibilité.

useHeadSafe pour le Contenu Généré par les Utilisateurs

Quand les balises meta incluent des entrées utilisateur, les vulnérabilités XSS deviennent une préoccupation. Le composable useHeadSafe assainit les valeurs avant injection.

vue
<!-- pages/profile/[username].vue -->
<script setup lang="ts">
const user = await useFetch(`/api/users/${route.params.username}`)

useHeadSafe({
  title: user.data.value?.displayName,
  meta: [
    { name: 'description', content: user.data.value?.bio },
  ],
})
</script>

Un nom d'utilisateur malveillant comme <script>alert('xss')</script> est échappé plutôt qu'exécuté. Le useHead standard ne sanitise pas, donc useHeadSafe est obligatoire pour tout contenu non fiable.

Module Nuxt SEO pour les Besoins Avancés

Le module Nuxt SEO regroupe la génération de sitemap, la gestion du robots.txt, le balisage schema.org et la génération d'images OG. Pour les projets nécessitant un outillage SEO complet au-delà des composables intégrés, ce module réduit le code répétitif.

nuxt.config.tstypescript
export default defineNuxtConfig({
  modules: ['@nuxtjs/seo'],
  site: {
    url: 'https://sharpskill.dev',
    name: 'SharpSkill',
  },
})

Le module génère automatiquement les sitemaps à partir des routes, gère la normalisation des slashs de fin et fournit des composables pour les données structurées. Les équipes maintenant de grands sites bénéficient de la configuration centralisée.

Passe à la pratique !

Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.

Bonnes Pratiques SEO Nuxt 4 pour la Production

  • Utiliser useSeoMeta pour toutes les balises SEO (title, description, Open Graph, Twitter Cards) avec l'autocomplétion TypeScript
  • Utiliser useHead pour les URLs canoniques, les balises hreflang, les données structurées et les scripts externes
  • Envelopper les balises meta statiques dans import.meta.server pour éliminer la surcharge de réactivité côté client
  • Inclure ogImageWidth, ogImageHeight et ogImageAlt pour les aperçus de partage social
  • Utiliser useHeadSafe pour tout contenu généré par les utilisateurs afin de prévenir les attaques XSS
  • Définir les valeurs par défaut au niveau app dans nuxt.config.ts et surcharger au niveau page uniquement si nécessaire
  • Tester avec Google Rich Results Test pour valider les données structurées
  • Vérifier le rendu dans l'onglet Network des DevTools du navigateur avec JavaScript désactivé pour simuler le comportement des robots
Défi du jour

Tu saurais repérer le bug en Vue.js / Nuxt.js ?

Un vrai bout de code, un bug caché, une tentative par jour. Sans compte pour essayer.

Anthony Fillion-Maillet

Écrit par

Anthony Fillion-Maillet

Fondateur de SharpSkill

Développeur fullstack depuis plus de 10 ans. Il dirige SharpSkill et répond de tout ce qui y est publié.

Mis à jour le 12 septembre 2026

Partager

Articles similaires