Apprends à configurer les données structurées dans React Router 7 et augmente l’impact SEO de tes pages grâce aux rich snippets et JSON-LD.
avec React Router 7
Posez vos questions 24/7 à notre IA experte en React Router 7
Validez vos acquis avec des quiz personnalisés et un feedback instantané
Tu as déjà optimisé tes balises title
et description
(voir la leçon
Configurer les balises meta SEO).
Prochaine étape : aider Google à comprendre ton contenu pour afficher un
résultat enrichi (rich snippet) : étoiles, image, durée d’une recette, prix…
Ces informations proviennent d’un bloc JSON-LD
placé dans le <head>
.
L’énorme avantage :
Dans React Router 7 (ex-Remix) c’est ultra simple : une resource route ou
la fonction meta()
suffit.
Au lieu d’écrire du JSON brut (casse-pieds !), on va utiliser
schema-dts
:
il expose tous les types Schema.org en TypeScript.
1npm install schema-dts
ArticleStructuredData
1import type { Article } from "schema-dts";23export function ArticleStructuredData(props: Article) {4return (5<script6type="application/ld+json"7dangerouslySetInnerHTML={{ __html: JSON.stringify(props) }}8/>9);10}
Pourquoi un composant ? Tu restes en JSX, tu bénéficies de l’autocomplétion et tu peux l’appeler depuis n’importe quelle route.
1import { ArticleStructuredData } from "~/components/ArticleStructuredData";2import { useLoaderData } from "react-router";3import { fetchArticle } from "~/server/articles.server";45/* ---------------- loader ---------------- */6export async function loader({ params }: Route.LoaderArgs) {7const article = await fetchArticle({ slug: params.slug });8if (!article)9throw new Response("Article introuvable", { status: 404 });10return article;11}1213/* ---------------- composant page ---------------- */14export default function ArticlePage() {15const article = useLoaderData<typeof loader>();1617return (18<>19<ArticleStructuredData20{"@context"="https://schema.org"}21{"@type"="Article"}22headline={article.title}23image={article.image}24datePublished={article.dateCreated.toISOString()}25author={{26"@type": "Person",27name: article.author,28}}29/* ^? autocomplétion assurée par schema-dts */30/>3132{/* …le reste de ton template Markdown / MDX… */}33</>34);35}
Points clés du transcript (reformulés) :
article
.meta()
Tu préfères la fonction traditionnelle ?
1import { generateMeta } from "@forge42/seo-tools/remix/metadata";2import { article as articleLD } from "@forge42/seo-tools/structured-data/article";34export const meta = ({ data }: Route.MetaArgs) =>5generateMeta(6{7title: data.title,8description: data.description,9url: data.slug, // absolu conseillé10},11[12{13"script:ld+json": articleLD({14"@type": "Article",15headline: data.title,16image: data.image,17datePublished: data.dateCreated.toISOString(),18author: { "@type": "Person", name: data.author },19}),20},21],22);
Cette approche colle au transcript : la lib Forge42 écrit le <script>
à
ta place. À toi de choisir la méthode qui te convient, l’important est que le
script atterrisse dans le <head>
.
Copie/colle le HTML généré ou pointe directement ton URL : tu dois voir « Aucun avertissement critique ».
Les SERP aiment connaître ton entité (marque, blog, association) :
1import { Organization } from "schema-dts";23export function RootStructuredData() {4const org: Organization = {5"@context": "https://schema.org",6"@type": "Organization",7name: "Algomax",8url: "https://algomax.fr",9logo: "https://algomax.fr/logo.svg",10};11return (12<script13type="application/ld+json"14dangerouslySetInnerHTML={{ __html: JSON.stringify(org) }}15/>16);17}
Place-le dans app/root.tsx
juste avant <Meta />
.
Ainsi, TOUTES les pages héritent de l’Organisation ; chaque article ajoute
ensuite son propre script.
Problème | Solution |
---|---|
Script rendu dans le body | Place-le via meta() ou dans un composant monté avant le premier <h1> . |
URL relatives (/cover.jpg ) | Convertis en URL absolues (https://…/cover.jpg ). |
Titre dupliqué | Supprime l’ancien <MetaTags> seulement dans la page où tu injectes generateMeta . |
Types inconnus (ex. TechArticle ) | Vérifie dans schema.org ; Google ne supporte pas tout. |
<script type="application/ld+json">
par type de page.url
, image
, logo
) sont absolues./login
, /register
) : pas de JSON-LD inutile.schema-dts
).Pousse ! Dans 48 h la Search Console devrait t’indiquer
“Améliorations → Article – Valides ✔︎”.
Un petit pas pour toi, un bond pour le CTR de ton blog 😎
Quelle est la principale différence entre les composants client et serveur dans React ?
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Quel hook permet de gérer les effets de bord dans un composant React ?
Comment implémenter la gestion des erreurs pour les requêtes API dans React ?
Quelle est la meilleure pratique pour déployer une application React en production ?