Traduction des métadonnées de page
Configuration des balises <title> et <description> localisées
Problème
Un utilisateur consulte une page en espagnol, et tout le contenu visible est correctement traduit. Cependant, l'onglet du navigateur et l'extrait de résultat du moteur de recherche affichent toujours le titre et la description en anglais. Cette incohérence des métadonnées crée une expérience utilisateur déroutante et nuit au référencement en présentant des informations non pertinentes dans les résultats de recherche.
Solution
Utilisez la fonction generateMetadata de Next.js dans vos pages et layouts. Cette fonction côté serveur peut charger les traductions correctes basées sur le paramètre lang (en utilisant la même logique de chargement de dictionnaire que vos composants) et retourner un objet metadata dynamique avec le titre et la description localisés.
Étapes
1. Créer une fonction pour charger les dictionnaires
Vous avez besoin d'un moyen de charger vos fichiers de traduction plats sur le serveur. Créez une fonction d'aide pour cela.
// app/get-dictionary.ts
import 'server-only';
type Messages = Record<string, string>;
const dictionaries: { [key: string]: () => Promise<Messages> } = {
en: () => import('@/dictionaries/en.json').then((module) => module.default),
es: () => import('@/dictionaries/es.json').then((module) => module.default),
};
export const getDictionary = async (lang: string) => {
const load = dictionaries[lang];
if (load) {
return load();
}
return dictionaries.en();
};
2. Définir les métadonnées sur une page
Dans votre fichier de page (par exemple, app/[lang]/about/page.tsx), exportez une fonction async appelée generateMetadata. Next.js l'appellera automatiquement lors du rendu de la page.
// app/[lang]/about/page.tsx
import { getDictionary } from '@/app/get-dictionary';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
};
// Cette fonction génère les métadonnées
export async function generateMetadata({ params }: Props): Promise<Metadata> {
// Charger le dictionnaire pour cette page
const dict = await getDictionary(params.lang);
return {
title: dict['about.title'], // par ex., "About Us" ou "Sobre Nosotros"
description: dict['about.description'],
};
}
// Le reste de votre composant de page
export default function AboutPage() {
return (
<div>
{/* Contenu de la page */}
<h1>...</h1>
</div>
);
}
3. Définir un modèle de titre dans la mise en page racine
Pour éviter de répéter le nom de votre site dans chaque titre, vous pouvez définir un modèle dans votre mise en page racine.
// app/[lang]/layout.tsx
import { getDictionary } from '@/app/get-dictionary';
import type { Metadata } from 'next';
type Props = {
params: { lang: string };
children: React.ReactNode;
};
// Vous pouvez également générer des métadonnées dans les mises en page
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const dict = await getDictionary(params.lang);
return {
// Ceci fournit un titre de base et un modèle
title: {
default: dict['site.name'], // par exemple, "Mon site génial"
template: `%s | ${dict['site.name']}`, // par exemple, "À propos | Mon site génial"
},
description: dict['site.description'],
};
}
export default async function RootLayout({ children, params }: Props) {
// ... reste de votre mise en page (chargement des fournisseurs, etc.)
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
);
}