# Un carrousel d’images ACF Gallery mal typé casse le build Next.js en pleine nuit

> Un déploiement automatisé échouait silencieusement chaque nuit parce qu'un champ ACF Gallery renvoyait parfois null au lieu d'un tableau vide. Voici le correctif défensif qui a réglé le problème.

- Auteur : Clément Hadrot
- Publié le : 2022-03-18
- Mis à jour le : 2022-03-18
- Catégorie : Headless &amp; API
- URL : https://wpmoderne.dev.wordpress-developpement.fr/headless/acf-gallery-null-typage-defensif-graphql-nextjs/

## L’essentiel

- Un champ Gallery jamais rempli renvoie null, pas un tableau vide
- Un .map() sur null fait planter tout le build
- Un typage défensif côté requête règle le problème une fois pour toutes

## Symptôme

Depuis une semaine, le déploiement automatisé nocturne d'un site immobilier échouait de manière intermittente, toujours aux alentours de trois heures du matin, sans schéma évident. Le lendemain, tout semblait fonctionner normalement en relançant manuellement le même build. Le client, lui, ne voyait rien d'anormal côté site en production puisque l'ancien build restait servi en cas d'échec du nouveau. C'est seulement en épluchant les journaux de la plateforme de déploiement que l'erreur exacte est apparue, toujours identique :

```
TypeError: Cannot read properties of null (reading 'map')
  at BienCard (components/BienCard.jsx:14:32)
```

## Diagnostic

Le champ en cause était un ACF Gallery nommé `photos_bien`, affiché en carrousel sur chaque fiche de bien immobilier. Le composant React itérait dessus sans précaution :

```
function BienCard({ bien }) {
  return (
    <div>
      {bien.photosBien.map((photo) => (
        <img key={photo.id} src={photo.sourceUrl} />
      ))}
    </div>
  )
}
```

Tant qu'un agent immobilier ajoutait au moins une photo à chaque nouveau bien, ce code fonctionnait sans accroc. Le problème survenait uniquement quand un bien était créé rapidement, sans photo au moment de la publication, une pratique fréquente en fin de journée pour « réserver » une annonce avant de la compléter le lendemain. Dans ce cas précis, WPGraphQL for ACF renvoie `null` pour le champ Gallery, et non un tableau vide comme on pourrait s'y attendre intuitivement. Les publications se faisaient généralement en fin de journée, ce qui explique la récurrence du plantage à trois heures du matin, heure du build automatisé nocturne suivant.

> L'essentiel à retenir : Un champ Gallery jamais rempli renvoie null, pas un tableau vide ; Un .map() sur null fait planter tout le build ; Un typage défensif côté requête règle le problème une fois pour toutes

## Correctif : un typage défensif au niveau de la requête

Le correctif le plus robuste ne consiste pas à ajouter une simple vérification `bien.photosBien?.map(...)` dans chaque composant qui consomme ce champ, une rustine qu'il faudrait reproduire partout où le champ est utilisé, avec le risque d'en oublier un. La solution retenue transforme la donnée une seule fois, au plus près de la requête GraphQL, via une fonction de normalisation appliquée systématiquement après récupération :

```
async function recupererBien(slug) {
  const donnees = await requeteGraphQL(REQUETE_BIEN, { slug })
  return normaliserBien(donnees.bien)
}

function normaliserBien(bien) {
  return {
    ...bien,
    photosBien: bien.photosBien ?? [],
  }
}
```

Ainsi, quel que soit l'endroit du code qui consomme `bien.photosBien`, la valeur reste toujours un tableau, potentiellement vide, jamais `null`. Le composant `BienCard` n'a même pas eu besoin d'être modifié : son `.map()` fonctionne désormais dans tous les cas, y compris sur un bien fraîchement créé sans aucune photo.

## Vérifier que le schéma GraphQL confirme bien ce comportement

Une requête d'introspection sur le schéma WPGraphQL a permis de confirmer que le champ est bien typé comme une liste nullable (`[MediaItem]`, sans point d'exclamation), et non comme une liste non nullable qui aurait garanti un tableau vide par défaut. C'est un comportement cohérent avec le fonctionnement d'ACF côté PHP, où un champ Gallery jamais rempli n'a simplement pas de valeur enregistrée en base, donc pas de tableau à retourner du tout.

## Prévention

- Toute fonction de récupération de données WPGraphQL passe désormais par une étape de normalisation explicite avant d'atteindre les composants React.
- Un test unitaire simule volontairement un bien sans photo pour vérifier que le rendu ne plante jamais, indépendamment du contenu réel présent en base au moment du test.
- La génération de types TypeScript, réalisée par ailleurs sur ce projet, aide à repérer visuellement les champs nullables du schéma, mais ne remplace pas une vérification explicite à l'exécution : TypeScript ne protège que du typage statique, pas d'une valeur réellement `null` au runtime.

> Un champ ACF vide n'est jamais un cas limite théorique : c'est une situation qui arrivera en production, tôt ou tard, dès qu'un contenu est créé avant d'être complété.

## En résumé

Ce plantage nocturne n'avait rien d'un bug caché dans Next.js ou dans WPGraphQL : c'était un cas d'usage réel, la création d'un bien sans photo, jamais testé avant la mise en production. Le correctif final tient en une ligne de normalisation, appliquée une seule fois, plutôt qu'en dizaines de vérifications défensives disséminées dans chaque composant qui consomme le champ concerné.
