Le rendu côté serveur, en anglais SSR (Server-Side Rendering), consiste à faire générer la page complète par le serveur avant de l'envoyer au navigateur, plutôt que de livrer une coquille vide que le navigateur remplit ensuite. L'intérêt est double : la page s'affiche immédiatement, et les moteurs de recherche voient un contenu réel plutôt qu'une page blanche. Pour un site dont la visibilité compte, c'est structurant.
Angular 21 propose ce mode, et il fonctionne très bien. Le problème, c'est qu'il a une façon particulière d'échouer : sans bruit. Quand le SSR se casse, il ne plante pas, il retombe silencieusement sur l'ancien comportement et sert une page vide que le navigateur remplit. Le site reste fonctionnel pour un visiteur humain, donc personne ne s'alarme, mais le bénéfice SEO et la rapidité d'affichage ont disparu. Voici les trois pièges à connaître, vécus en production sur ce site.
Piège 1 : un échec qui ne se voit pas
Ce premier piège ne provoque aucune panne : il les masque. Et c'est précisément pour ça qu'il vient en tête, car sans lui, les deux suivants se repéreraient en quelques minutes.
Le réflexe naturel pour vérifier qu'un site répond est de regarder son code de réponse : 200, tout va bien. Sauf qu'une page rendue côté serveur et une coquille vide renvoient toutes les deux un code 200. Le code de réponse ne distingue pas les deux situations. On peut donc avoir un SSR mort pendant des jours sans le voir, parce que tous les indicateurs superficiels sont au vert.
La seule vérification fiable consiste à inspecter le contenu réel de la page renvoyée par le serveur : le contenu attendu est-il présent dès la réponse, ou la page est-elle vide en attendant que le navigateur la remplisse ? C'est ce contrôle, et non le code de réponse, qui doit faire partie de la surveillance. Une fois ce principe posé, les deux pièges suivants deviennent identifiables.
Piège 2 : les hôtes autorisés bloquent tout
Angular 21 intègre une protection contre une attaque classique où un visiteur malveillant ment sur le nom de domaine qu'il prétend visiter. Pour s'en prémunir, le framework demande la liste des noms de domaine légitimes.
Le piège est dans la valeur par défaut. À la création du projet, cette liste est posée vide. On pourrait croire qu'une liste vide signifie « aucune restriction, tout est autorisé ». C'est l'inverse : elle signifie « aucun domaine autorisé », donc tout est bloqué. Y compris l'adresse locale en développement. Le site retombe en page vide dès le premier lancement, avec un message d'avertissement qui prévient que cela deviendra une erreur franche dans une version future.
Le correctif est simple une fois qu'on le sait : déclarer explicitement les adresses légitimes, l'adresse locale pour le développement et le vrai nom de domaine pour la production. Mais tant qu'on ignore que la valeur par défaut est restrictive, on cherche au mauvais endroit.
Piège 3 : les en-têtes du proxy non déclarés cassent le rendu
Celui-ci est plus subtil et m'a coûté plusieurs jours. En production, le site n'est presque jamais exposé directement : un intermédiaire technique, le reverse-proxy, se place devant l'application et transmet les requêtes. En les transmettant, il ajoute des informations sur le visiteur d'origine, sous forme d'en-têtes techniques.
Angular 21 considère ces en-têtes ajoutés comme suspects par défaut, sauf ceux qu'on lui a explicitement déclarés comme fiables. Et la liste fiable par défaut est incomplète : elle ne couvre pas tous les en-têtes qu'un proxy émet en pratique. Conséquence, chaque requête de production portait un en-tête non déclaré, ce qui déclenchait le repli silencieux : cent pour cent du trafic servi en page vide, alors que tout fonctionnait parfaitement en local, puisque sans proxy ces en-têtes n'existent pas.
C'est l'archétype du bug qui ne se reproduit pas sur le poste du développeur. La solution tient en deux temps : déclarer comme fiables exactement les en-têtes que votre proxy émet, ni plus ni moins, et configurer le proxy pour qu'il neutralise ceux qu'il n'utilise pas, afin qu'un visiteur ne puisse pas en injecter de faux.
La leçon commune
Ces trois pièges partagent un trait : aucun ne se manifeste pendant le développement. La liste d'hôtes vide ne pose problème que parce que la production a un vrai domaine ; les en-têtes de proxy n'existent qu'en production ; et le mode d'échec silencieux fait que rien ne crie. C'est exactement le genre de problème qui passe entre les mailles d'une recette superficielle et se découvre des semaines plus tard, quand on s'étonne que le référencement stagne.
La parade n'est pas le génie, c'est la rigueur : vérifier la bonne chose (le contenu réel servi, pas le code de réponse), et placer ce contrôle dans la surveillance automatique pour qu'une régression se voie le jour où elle survient, pas des semaines après. C'est précisément ce type de vigilance que je documente et que je livre avec les applications : une mise en production réussie n'est pas une page qui répond, c'est une page qui répond pour la bonne raison.
