Explorer
KNOW-PAT-141

Composant SEOLanding réutilisable pour pages catégories statiques

Domaine
web-uiux
Type
pattern
Priorité
P1

Parent : [[INDEX-WEB-UIUX]]

Composant SEOLanding réutilisable

Problème

Créer des pages SEO (landing pages catégories) une par une est répétitif et error-prone. Chaque page a besoin de :

  • Metadata Next.js (title, description, keywords, OpenGraph, Twitter)
  • JSON-LD structuré
  • Layout cohérent (hero, features, related links, CTA)
  • Textes et liens internes optimisés

Solution

Créer un composant générique SEOLanding.tsx + fonction seoMetadata() exportés et utilisés par chaque page catégorie.

// app/components/SEOLanding.tsx
export type SEOLandingProps = {
  title: string; description: string; keywords: string
  h1: string; intro: string
  features: { title: string; desc: string }[]
  related: { label: string; href: string }[]
  ctaText: string; ctaHref: string
  jsonLd: Record<string, unknown>
}

export function seoMetadata({ title, description, keywords, path }) {
  return {
    title, description, keywords,
    alternates: { canonical: `https://site.com${path}` },
    openGraph: { title, description, url: `https://site.com${path}`, siteName: 'Site', type: 'website' },
    twitter: { card: 'summary_large_image', title, description },
  }
}
// app/scripts/page.tsx
export const metadata = seoMetadata({
  title: 'Scripts FiveM...',
  description: '...',
  keywords: '...',
  path: '/scripts',
})

export default function ScriptsPage() {
  return <SEOLanding title="..." h1="..." intro="..." features={[...]} related={[...]} ... />
}

Exemple

Correct

import { SEOLanding, seoMetadata } from '../components/SEOLanding'

export const metadata = seoMetadata({ title: '...', path: '/scripts' })
export default function Page() {
  return <SEOLanding h1="..." features={[...]} ... />
}

Incorrect

// Copier-coller le layout complet pour chaque page
export default function Page() {
  return (
    <main>
      <section style={{ background: '...' }}>
        <h1>Scripts</h1>
        {/* ... 200 lignes dupliquées ... */}
      </section>
    </main>
  )
}

Pourquoi ça marche

  • DRY : une seule source de vérité pour le layout SEO
  • Prerender statique automatique par Next.js App Router
  • JSON-LD cohérent sur toutes les pages
  • Facile à étendre (ajouter FAQ, breadcrumb, etc.)

Quand ne PAS l'utiliser

  • Pages avec un contenu très différent du template (ex: blog posts longs)
  • Pages nécessitant du SSR avec des données dynamiques
  • Landing pages avec des sections uniques (vidéo hero, carousel, etc.)

Source

  • Projet : ProjectAlpha
  • Contexte : Création de 7 pages SEO catégories (/scripts, /vehicles, /mappings...)
  • Validé le : 2026-05-17