Déployer et superviser

Déploiement sur Vercel

Un projet Vercel par instance, même dépôt, même commande de build, variables différentes. L'auto-hébergement (pnpm build:<instance>, artefact standalone) reste possible sans changement : les deux chemins coexistent.

Pourquoi la donnée est dans le dépôt

Vercel ne moissonne pas. La moisson demande 20 minutes, 2,1 Go et onze sources externes ; mise dans le chemin d'un déploiement, elle en fait un déploiement qui casse le jour où une source tousse — et theses.fr est déjà en échec. Les JSON publiés sont donc versionnés :

VersionnéTaillePourquoi
data/public/*/*.json18 MoLu au build par chaque page : sans eux, site vide
data/public/*/markdown/60 MoNon versionné — rien ne le lit dans l'application
data/raw/2,1 GoNon versionné — réponses brutes des sources
Sortie de build6,7 GoNon versionnée — 287 905 fichiers, Vercel la refait

Régénérer et pousser :

TerminalCode
pnpm data:extract && pnpm data:build # ou pnpm data:build seul si data/raw est à jour pnpm data:freeze # fige la nouvelle référence git add data/public tests/reference && git commit -m "Données régénérées"

Le hook de pré-push refuse un dépôt où la donnée manque, n'est pas suivie, ou diverge de la référence figée.

Le piège de l'index de recherche

L'index Pagefind se construit à partir du HTML des pages, donc après next build. Trois pièges en ont découlé, chacun trouvé en déployant pour de vrai :

  1. next build fige le contenu de public/. Un index écrit après n'est pas servi.
  2. Pagefind déduit la racine du site de l'emplacement de son propre script, en coupant à /pagefind/. Servi depuis /_next/static/pagefind/…, il préfixait toutes ses URL de résultat par /_next/static : les titres restaient justes, tous les liens menaient à un 404. Le composant retire ce préfixe (INDEX_ROOT), et deux tests couvrent les deux emplacements.
  3. Sur Vercel, Next tourne avec un adaptateur (NEXT_ADAPTER_PATH), qui change deux choses :
    • les pages pré-rendues sont rangées sous .next/server/route-cache/APP_PAGE/<empreinte de la route>/$/<chemin>.html au lieu de .next/server/app/<chemin>.html : Pagefind, pointé sur l'ancien dossier, ne trouvait rien (« Found 0 files matching … ») ;
    • la liste des fichiers à déployer est remise à l'adaptateur à la fin de next build : un index écrit ensuite, même dans .next/static/, est construit mais jamais servi (404, et la page de recherche affiche « index non construit »).

D'où la solution : scripts/pagefind-adapter.mjs s'intercale devant l'adaptateur de Vercel. onBuildComplete est le seul moment où le HTML pré-rendu existe et où la liste des fichiers à déployer est encore ouverte. L'adaptateur y rassemble les pages à leur chemin public, construit l'index, le déclare sous /pagefind/<instance>/, puis passe la main à l'adaptateur de Vercel, inchangé. Une seule passe de build.

Build Vercel : l'index ajouté par un adaptateur intercalé

L'index est servi à son emplacement standard, /pagefind/<instance>/, sans variable à poser ; next.config.ts exclut déjà ce chemin de la réécriture vers /fr. NEXT_PUBLIC_PAGEFIND_BASE reste disponible pour le servir ailleurs, par exemple depuis un stockage objet.

Vérifié en local le 29/10/2026 sur Paris 1, avec un adaptateur de test dans le rôle de celui de Vercel : il recevait 0 fichier d'index quand l'index était écrit après le build (et aussi après une seconde passe de next build, essayée puis écartée : public/ n'entre pas dans la liste remise à l'adaptateur), 4 829 avec l'adaptateur intercalé.

Mettre en place un projet, en ligne de commande

Un projet Vercel par site, tous sur le même dépôt : un par instance (racine du dépôt, vercel.json de la racine), un pour la documentation (racine docs/, son propre vercel.json). Chaque push sur main les reconstruit tous.

scripts/vercel-project.mjs crée le projet, règle son dossier racine et son framework, pose les variables et le relie au dépôt GitHub. Il est rejouable : sur un projet existant, il met à jour les réglages sans écraser l'adresse publique (sauf --site-url) ni le jeton de métriques.

TerminalCode
npx vercel@65.7.0 login # une fois par poste, ou export VERCEL_TOKEN=… pnpm vercel:project docs --domain lucarne.vicode.fr # → lucarne.vicode.fr pnpm vercel:project saclay --domain saclay.lucarne.vicode.fr --demo # → saclay.lucarne.vicode.fr pnpm vercel:project paris1 --domain paris1.lucarne.vicode.fr --demo # → paris1.lucarne.vicode.fr # Options : --domain <hôte>, --demo, --site-url <url>, --name <projet>, --scope <équipe>, --deploy (premier déploiement tout de suite), # --dry-run (affiche les commandes sans rien faire)
ProjetRacineFrameworkVariables posées
Documentationdocs/ViteDOCS_SITE_URL
Instance <id>.Next.jsNEXT_PUBLIC_RESEARCH_INSTANCE, NEXT_PUBLIC_SITE_URL, METRICS_TOKEN (généré, secret)

Ajouter une nouvelle instance revient à créer instances/<id>/, publier ses données (pnpm data:build --instance <id>), les commiter, puis pnpm vercel:project <id> : le script refuse une instance dont les données ne sont pas dans le dépôt. La procédure complète est dans Marque blanche.

--deploy envoie le dossier local à Vercel. .vercelignore écarte ce qui ne doit jamais partir : data/raw (2,1 Go, des noms de personnes), les sorties de build (.next*, plusieurs Go), les node_modules. Sans --deploy, rien n'est envoyé depuis le poste : Vercel construit depuis Git.

Les mêmes réglages restent possibles à la main dans le tableau de bord : copier instances/<id>/vercel.env.example dans Settings → Environment Variables.

Ce qui reste à vérifier chez vous

Le nombre de fichiers. La sortie compte environ 142 500 fichiers (pages, charges RSC, statique) plus 23 787 pour l'index. C'est la limite la plus susceptible de bloquer, bien avant la durée de build. Si elle est dépassée, sortir l'index vers un stockage objet retire d'un coup 23 787 fichiers et 110 Mo : NEXT_PUBLIC_PAGEFIND_BASE accepte déjà une URL absolue.

La durée. Moins de 4 minutes mesurées ici, pour 23 696 pages, plus l'indexation (moins d'une minute). La limite de Vercel dépend du plan.