# 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.

- Auteur : Clément Hadrot
- Publié le : 2021-11-16
- Mis à jour le : 2021-11-16
- Catégorie : Headless &amp; API
- URL : https://wpmoderne.dev.wordpress-developpement.fr/headless/nextjs-wordpress-headless-guide-pages-router/

## L’essentiel

- 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

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.
