aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Développement Web

SEO Next.js : titre, OG et canonical avec Metadata API

Quand on parle de SEO Next.js, la première chose qui vient à l'esprit est de remplir correctement le <head> de la page : un titre pertinent, une description explicite, des balises Open Graph pour le partage social et un lien canonical qui évite le contenu dupliqué. La Metadata API livrée avec l'App Router permet de faire tout cela sans écrire le <head> à la main, de manière typée et résolue côté serveur. Dans ce guide, je détaille une configuration pratique, de l'objet metadata statique à la fonction dynamique generateMetadata.

Qu'est-ce que la Metadata API ?

Dans l'App Router (Next.js 13.2 et versions ultérieures), chaque fichier layout.tsx et page.tsx peut exporter des métadonnées de deux façons : un objet metadata pour des valeurs constantes, ou une fonction asynchrone generateMetadata pour des valeurs qui dépendent de la requête ou des données. Next.js les lit et génère le <head> de la page à votre place. Une règle importante : ces exports ne fonctionnent que dans des fichiers Server Component ; vous ne pouvez pas exporter de métadonnées depuis un fichier marqué "use client".

Titre et description avec des métadonnées statiques

La forme la plus simple consiste à exporter un objet constant. On en place généralement un global dans le app/layout.tsx racine, puis on en ajoute des spécifiques par route.

// app/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: {
    default: "aslain.dev — Développement web & jeux",
    template: "%s | aslain.dev",
  },
  description: "Guides sur le web, les serveurs de jeux et les bots Discord.",
};

Le champ title.template est un outil puissant : les pages enfants ne fournissent que leur propre titre, et Next.js l'insère dans %s en ajoutant le nom du site. Par exemple, si une page définit title: "Contact", le résultat devient Contact | aslain.dev. Vous cessez de répéter votre marque dans chaque titre à la main.

SEO Next.js dynamique avec generateMetadata

Sur les routes dont le contenu provient d'une base de données — articles de blog, pages produit — le titre et la description doivent aussi être dynamiques. C'est là qu'intervient generateMetadata. Elle reçoit le même argument params que la page elle-même, récupère les données et retourne les métadonnées.

// app/blog/[slug]/page.tsx
import type { Metadata } from "next";

export async function generateMetadata(
  { params }: { params: Promise<{ slug: string }> }
): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);

  return {
    title: post.title,
    description: post.excerpt,
  };
}

Avec Next.js 15, params est devenu une Promise, vous devez donc le résoudre avec await. Note de performance importante : les appels fetch effectués dans generateMetadata sont dédupliqués par la mémoïsation des requêtes de Next.js lorsqu'ils sont répétés dans le même composant de page ; ne craignez donc pas de récupérer deux fois les mêmes données.

Cartes Open Graph et Twitter

L'apparence de votre lien lorsqu'il est partagé sur WhatsApp, X ou LinkedIn est contrôlée par les balises Open Graph. La Metadata API les expose proprement sous les clés openGraph et twitter.

export const metadata: Metadata = {
  openGraph: {
    title: "Guide SEO Next.js",
    description: "Titre, OG et canonical avec la Metadata API.",
    url: "https://aslain.dev/blog/nextjs-seo",
    siteName: "aslain.dev",
    images: [{ url: "/og/nextjs-seo.png", width: 1200, height: 630 }],
    locale: "fr_FR",
    type: "article",
  },
  twitter: {
    card: "summary_large_image",
    title: "Guide SEO Next.js",
    images: ["/og/nextjs-seo.png"],
  },
};
  • Taille de l'image : 1200×630 pixels est le ratio standard attendu par les plateformes sociales.
  • type: "article" : le bon type OG pour les articles de blog ; utilisez "website" pour la page d'accueil.
  • Si vous ne précisez pas la carte Twitter séparément, la plupart des champs sont hérités d'Open Graph ; il reste recommandé de définir explicitement le type card.

Canonical et alternatives de langue

Si le même contenu est accessible depuis plusieurs URL (barre oblique finale, paramètres de suivi), une balise canonical est indispensable pour indiquer aux moteurs de recherche l'adresse de référence. La Metadata API la fournit sous alternates.

export const metadata: Metadata = {
  metadataBase: new URL("https://aslain.dev"),
  alternates: {
    canonical: "/blog/nextjs-seo",
    languages: {
      "fr-FR": "/fr/blog/nextjs-seo",
      "en-US": "/en/blog/nextjs-seo",
    },
  },
};

Définissez toujours metadataBase : les chemins relatifs (comme /blog/... ou /og/...) sont résolus en URL absolues par rapport à cette base. Si vous l'omettez, Next.js émet un avertissement en développement et les images OG peuvent ne pas s'afficher sur certaines plateformes faute d'URL absolue. Les alternatives listées sous languages se transforment en balises hreflang, renforçant le SEO multilingue.

Erreurs fréquentes

  • Export depuis un composant client : exporter des métadonnées depuis un fichier "use client" ne fait rien en silence ; gardez les métadonnées dans un Server Component.
  • Oublier metadataBase : les images OG et le canonical sont cassés car ils restent relatifs.
  • Définir le titre deux fois : title et openGraph.title peuvent différer ; sans cohérence, le partage prête à confusion.
  • Mélanger un <head> manuel : dans l'App Router, n'écrivez pas d'élément <head> à la main — la Metadata API doit être la source unique de vérité.

Questions fréquentes

Faut-il utiliser l'objet metadata ou generateMetadata ?

Si les valeurs sont constantes (pages statiques, layout racine), l'objet metadata est plus simple et plus rapide. Si le titre ou la description provient de données, de params ou de la requête, utilisez generateMetadata. N'exportez pas les deux depuis le même fichier ; Next.js ne l'autorise pas.

La Metadata API génère-t-elle aussi les fichiers sitemap et robots ?

Oui. Les fichiers app/sitemap.ts et app/robots.ts relèvent des conventions de métadonnées basées sur les fichiers, et Next.js les transforme automatiquement en points d'accès /sitemap.xml et /robots.txt. De même, app/icon.png et app/opengraph-image.tsx sont également reconnus.

generateMetadata ralentit-il le chargement des pages ?

Généralement non. Ses appels de données utilisent le même cache que le composant de page (mémoïsation des requêtes), donc le même fetch ne déclenche pas deux requêtes réseau. Évitez tout de même les requêtes inutilement lourdes et privilégiez des sources de données pouvant être mises en cache.

Vous voulez poser les bases SEO Next.js de votre site de zéro, ou auditer vos métadonnées existantes ? Construisons la structure App Router, Open Graph et canonical autour de votre projet — contactez-moi.

Bu kategorideki tüm yazılar →

Devamı için