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é | Taille | Pourquoi |
|---|---|---|
data/public/*/*.json | 18 Mo | Lu au build par chaque page : sans eux, site vide |
data/public/*/markdown/ | 60 Mo | Non versionné — rien ne le lit dans l'application |
data/raw/ | 2,1 Go | Non versionné — réponses brutes des sources |
| Sortie de build | 6,7 Go | Non versionnée — 287 905 fichiers, Vercel la refait |
Régénérer et pousser :
Code
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 :
next buildfige le contenu depublic/. Un index écrit après n'est pas servi.- 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. - 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>.htmlau 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 »).
- les pages pré-rendues sont rangées sous
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.
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.
Code
| Projet | Racine | Framework | Variables posées |
|---|---|---|---|
| Documentation | docs/ | Vite | DOCS_SITE_URL |
Instance <id> | . | Next.js | NEXT_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.