vendredi 25 septembre 2026

À propos

Contact

Headless & API

Next.js et WordPress headless : le guide complet du Pages Router

Construisez un blog headless statique avec Next.js Pages Router et l'API REST WordPress, de getStaticProps au SEO de base avec next/head.

Par Clément Hadrot • 16 novembre 2021 • 4 min de lecture • Aucun commentaire
Next.js et WordPress headless : le guide complet du Pages Router

Next.js s’est imposé comme l’un des frameworks React les plus adoptés pour bâtir des frontends headless, notamment grâce à son système de génération de pages statiques au build. Combiné à l’API REST WordPress, il permet de construire un blog rapide, bien référencé, tout en conservant WordPress comme back-office de contenu familier pour les équipes éditoriales.

Ce tutoriel construit, étape par étape, un blog headless minimal avec le Pages Router de Next.js : la liste des articles sur la page d’accueil, une page de détail par article générée dynamiquement, et une gestion de base du référencement.

Structure du projet

Un projet Next.js classique organise ses pages dans le dossier pages/. Pour notre blog headless, deux fichiers suffisent à démarrer : pages/index.js pour la liste des articles, et pages/articles/[slug].js pour la page de détail, où [slug] signale à Next.js une route dynamique.

Récupérer les articles au build avec getStaticProps

La fonction getStaticProps, exécutée côté serveur au moment du build, permet de récupérer les données avant même que la page ne soit générée en HTML statique :

// pages/index.js
export async function getStaticProps() {
  const reponse = await fetch(
    'https://exemple.fr/wp-json/wp/v2/posts?_embed&per_page=10'
  );
  const articles = await reponse.json();

  return {
    props: { articles },
    revalidate: 60,
  };
}

export default function Accueil( { articles } ) {
  return (
    <ul>
      {articles.map( ( article ) => (
        <li key={article.id}>
          <a href={`/articles/${article.slug}`}>{article.title.rendered}</a>
        </li>
      ) )}
    </ul>
  );
}

L’option revalidate: 60 active l’ISR (Incremental Static Regeneration), disponible depuis Next.js 9.5 : la page reste statique, mais Next.js la régénère automatiquement en arrière-plan si une requête arrive plus de soixante secondes après la dernière génération. Nous y reviendrons plus en détail dans un prochain article dédié à l’ISR combinée aux webhooks WordPress.

L'essentiel à retenir : getStaticProps récupère les données au build ; getStaticPaths génère les pages dynamiques par slug ; L'ISR permet de rafraîchir le contenu sans tout reconstruire

Générer les pages dynamiques avec getStaticPaths

Pour une route dynamique comme [slug].js, Next.js a besoin de savoir à l’avance quelles pages générer. C’est le rôle de getStaticPaths, qui liste tous les slugs possibles :

// pages/articles/[slug].js
export async function getStaticPaths() {
  const reponse = await fetch(
    'https://exemple.fr/wp-json/wp/v2/posts?_fields=slug&per_page=100'
  );
  const articles = await reponse.json();

  return {
    paths: articles.map( ( article ) => ( {
      params: { slug: article.slug },
    } ) ),
    fallback: 'blocking',
  };
}

export async function getStaticProps( { params } ) {
  const reponse = await fetch(
    `https://exemple.fr/wp-json/wp/v2/posts?slug=${params.slug}&_embed`
  );
  const [ article ] = await reponse.json();

  if ( ! article ) {
    return { notFound: true };
  }

  return { props: { article }, revalidate: 60 };
}

L’option fallback: 'blocking' mérite une attention particulière : elle permet de générer à la volée une page qui n’existait pas encore au build (un article publié après le dernier build), sans afficher de page d’erreur ni d’état de chargement intermédiaire.

Afficher le contenu de l’article

Le contenu HTML renvoyé par l’API REST WordPress doit être injecté avec précaution. Next.js/React n’interprète pas du HTML brut par défaut : il faut utiliser dangerouslySetInnerHTML, en toute conscience que le contenu provient d’une source de confiance (votre propre WordPress) :

export default function Article( { article } ) {
  return (
    <article>
      <h1>{article.title.rendered}</h1>
      <div
        dangerouslySetInnerHTML={{ __html: article.content.rendered }}
      />
    </article>
  );
}

Un minimum de SEO avec next/head

Pour un blog, le référencement reste un critère central. Le composant Head de Next.js permet d’injecter les balises meta essentielles depuis les données récupérées :

import Head from 'next/head';

export default function Article( { article } ) {
  return (
    <>
      <Head>
        <title>{article.title.rendered}</title>
        <meta
          name="description"
          content={article.excerpt.rendered.replace( /<[^>]*>/g, '' )}
        />
      </Head>
      {/* contenu de l'article */}
    </>
  );
}

Sur un vrai projet, extrayez systématiquement la logique d’appel à l’API REST dans un module partagé plutôt que de dupliquer les fetch dans chaque page. Cela facilite grandement la migration future vers WPGraphQL ou vers une autre source de données.

En résumé

Le Pages Router de Next.js, associé à getStaticProps et getStaticPaths, offre une base solide et éprouvée pour un blog headless WordPress rapide et bien référencé. L’ISR, activée par la simple option revalidate, permet déjà de garder le contenu relativement à jour sans reconstruire l’intégralité du site à chaque publication. Nous approfondirons cette mécanique, combinée à des webhooks WordPress pour une revalidation à la demande, dans un prochain article.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi