Quand j'ai construit ce portfolio, j'ai mis export const dynamic = "force-dynamic" sur toutes les pages publiques. Le raisonnement : le contenu vit en base SQLite, je l'édite depuis un panneau d'admin, donc les pages doivent être dynamiques pour toujours afficher la dernière version.
Le raisonnement était faux.
## Le vrai coût
Mon contenu change peut-être une fois par semaine. Mes pages, elles, interrogeaient la base à chaque visite. Pour un site perso, ça tient — SQLite est rapide et le trafic est modeste. Mais c'est du travail inutile à chaque requête, et surtout ça m'enlevait tout ce que Next.js sait faire de mieux : servir du HTML déjà rendu.
## La bonne réponse : ISR + invalidation
La solution tenait en deux morceaux :
// sur chaque page publique
export const revalidate = 3600;// appelé par chaque mutation de l'admin
import { revalidatePath } from "next/cache";
export function revalidatePublic() {
for (const p of ["/", "/projets", "/parcours", "/a-propos", "/contact"]) {
revalidatePath(p);
}
}Les pages sont statiques. Quand je modifie quelque chose dans l'admin, la mutation invalide le cache et la page se régénère à la prochaine visite. Le revalidate = 3600 n'est qu'un filet de sécurité.
## Le piège qui a cassé mon déploiement
En passant à l'ISR, mon build s'est mis à interroger la base au moment du build (via generateStaticParams et le sitemap). Or j'avais ajouté des colonnes au schéma Prisma… et mon script de déploiement ne faisait pas de prisma db push. Résultat : build rouge en production, avec une erreur limpide une fois qu'on la lit vraiment :
The column `main.Project.problem` does not exist in the current database.Leçon : dès qu'une page est prérendue, le build a besoin d'une base à jour. Mon script de déploiement fait maintenant prisma db push avant next build, dans cet ordre, à chaque fois.
## Ce que je retiens
- Le réflexe « mon contenu est en base donc mes pages sont dynamiques » est un faux ami.
- L'invalidation à la mutation est le bon modèle : le lecteur paie zéro, l'éditeur paie une revalidation.
- Un site statique se voit : le portfolio répond instantanément, même quand le VPS est occupé.