BaliseTonSite

Images, Fonts & Metadata

Optimise tout ce qui rend ton site beau et visible sur Google.

7.1next/image : des images intelligentes

Le composant Image de Next.js remplace la balise <img> classique. Il fait tout ce que tu devrais faire toi-même mais que personne ne fait :

  • Compression automatique : tes images de 5 Mo deviennent légères sans perdre en qualité.
  • Lazy loading : les images ne se chargent que quand elles arrivent dans le viewport.
  • Taille adaptée : l'image servie est dimensionnée pour l'écran du visiteur.
  • Format moderne : conversion en WebP ou AVIF automatiquement.
  • Pas de CLS : l'espace est réservé avant le chargement (pas de saut de page).
TSXtsx
import Image from 'next/image'

export default function ProfilPage() {
  return (
    <div>
      {/* Image locale (dans /public) */}
      <Image
        src="/photo-profil.jpg"
        alt="Ma photo de profil"
        width={300}
        height={300}
      />

      {/* Image distante */}
      <Image
        src="https://example.com/photo.jpg"
        alt="Photo externe"
        width={800}
        height={400}
      />
    </div>
  )
}
TSXtsx
// next.config.ts

const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
      },
    ],
  },
}

export default nextConfig

7.2Image en fill : remplir un conteneur

Parfois tu ne connais pas les dimensions exactes de l'image (avatar dynamique, image d'un CMS...). Utilise le mode fill :

TSXtsx
<div className="relative w-full h-64">
  <Image
    src="/hero-banner.jpg"
    alt="Bannière"
    fill
    className="object-cover rounded-xl"
  />
</div>

L'image remplit son conteneur parent (qui doit être en position: relative). Avec object-cover, elle crop proprement sans se déformer. Parfait pour les bannières et les cards.

7.3next/font : des polices sans clignotement

Tu connais ce moment agaçant où la page charge avec une police par défaut, puis "saute" quand la vraie police arrive ? Next.js élimine ce problème avec next/font.

TSXtsx
// app/layout.tsx

import { Inter, Fira_Code } from 'next/font/google'

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
})

const firaCode = Fira_Code({
  subsets: ['latin'],
  variable: '--font-fira-code',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="fr" className={`${inter.variable} ${firaCode.variable}`}>
      <body className="font-sans">
        {children}
      </body>
    </html>
  )
}

Les avantages :

  • Zero layout shift : la police est intégrée au build, pas téléchargée après coup.
  • Self-hosted : pas de requête vers Google Fonts. Mieux pour la vie privée et la vitesse.
  • Variables CSS : tu peux utiliser la police partout via var(--font-inter).

7.4Metadata : le SEO en pilote automatique

Les métadonnées (titre, description, Open Graph...) sont essentielles pour que Google comprenne ta page et pour avoir de beaux previews sur les réseaux sociaux.

Next.js te propose deux façons de les définir :

Metadata statique (le plus courant)

TSXtsx
// app/layout.tsx ou n'importe quelle page

import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    default: 'Mon Super Site',
    template: '%s | Mon Super Site',  // Les sous-pages héritent
  },
  description: 'Le meilleur site du monde pour apprendre Next.js',
  openGraph: {
    title: 'Mon Super Site',
    description: 'Apprenez Next.js facilement',
    images: ['/og-image.png'],
  },
}

Metadata dynamique (par page)

TSXtsx
// 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 article = await getArticle(slug)

  return {
    title: article.title,
    description: article.excerpt,
    openGraph: {
      images: [article.coverImage],
    },
  }
}

Avec generateMetadata, chaque page a son propre titre et sa propre description. Google adore ça.

7.5Héritage des métadonnées

Les métadonnées fonctionnent comme les layouts : elles s'héritent et se fusionnent du layout racine vers les sous-pages.

Bashbash
app/
├── layout.tsx         # title: "Mon Site" (défaut global)
├── blog/
   ├── layout.tsx     # description: "Tous mes articles"
   └── [slug]/
       └── page.tsx   # title: "Mon Article" → affiche "Mon Article | Mon Site"

Grâce au template: '%s | Mon Super Site', les sous-pages affichent automatiquement leur titre suivi du nom du site. Pas besoin de le répéter partout.

Verifie tes acquis

5 questions pour valider ce chapitre

1. Quel avantage principal apporte le composant next/image par rapport a une balise <img> classique ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM terminé sauvegarde ton score. Crée ton profil gratuitement pour débloquer toutes les évaluations du site et retrouver tes résultats plus tard.

Commencer l'aventure
Déjà membre ?Connecte-toi