Corriger les URLs propres de Quartz sur Sevalla

Quartz gĂ©nĂšre ses liens internes sans extension : un lien vers cette page pointe vers /dĂ©veloppement/corriger-les-urls-propres-de-quartz-sur-sevalla, jamais vers la mĂȘme adresse en .html. C’est un choix assumĂ© du projet (le type FullSlug est documentĂ© “no file extension”) qui laisse Ă  l’hĂ©bergeur le soin de faire correspondre /xxx au fichier xxx.html rĂ©ellement gĂ©nĂ©rĂ©.

Sur Sevalla, qui hĂ©berge ce blog, sans rien configurer ça donne une 404 sur le moindre lien interne cliquĂ©. Le fichier existe, mais pas l’URL demandĂ©e.

Pretty URLs

Sevalla propose un toggle “Pretty URLs” dans Static Site → Settings → Redirects, prĂ©vu justement pour ce cas. Je l’ai activĂ©, les 404 ont disparu.

Ça a tenu des mois, jusqu’à une mise Ă  jour de Quartz (le cƓur et les 44 plugins communautaires que j’utilise). AprĂšs avoir poussĂ© les changements, plus aucun style ni script sur le site, sauf sur la page d’accueil.

Rien ne le signalait dans l’interface : Sevalla sert sa page 404 personnalisĂ©e avec un statut 200, donc l’échec des CSS et JS ne se voit qu’en ouvrant l’onglet rĂ©seau du navigateur.

En creusant : “Pretty URLs” ne fait pas une réécriture interne, il fait une vraie redirection HTTP vers une URL avec un slash final (/dĂ©veloppement/mon-article/ au lieu de /dĂ©veloppement/mon-article). Or Quartz calcule ses chemins CSS/JS en relatif, en supposant que la page est un fichier : ../component-styles.css remonte Ă  la racine depuis lĂ . Avec le slash final, le navigateur traite l’URL comme un dossier, et ../ remonte d’un cran de trop.

Le cache a bien failli me faire tourner en rond pendant le diagnostic : navigateur et Cloudflare, qui est devant Sevalla, cachent les redirections 3xx de façon agressive. Une fois la correction faite cĂŽtĂ© serveur, plusieurs rechargements donnaient encore l’impression que rien n’avait changĂ©, alors que curl confirmait que si.

Ce qui marche

DĂ©sactiver “Pretty URLs” sur Sevalla, et ajouter un fichier _redirects (le format Netlify, que Sevalla supporte aussi) Ă  la racine de public/ :

/* /:splat.html 200

Le 200 fait toute la diffĂ©rence avec une redirection : c’est une réécriture cĂŽtĂ© serveur, pas un renvoi au navigateur. Le contenu de xxx.html est servi directement Ă  l’URL xxx, qui ne change jamais, donc les chemins relatifs de Quartz restent corrects. L’équivalent d’un try_files nginx, ou du cleanUrls: true de Vercel.

Je ne maintiens pas ce fichier Ă  la main, il est gĂ©nĂ©rĂ© Ă  chaque build par un petit plugin Ă©metteur que j’ai ajoutĂ© au moteur Quartz (quartz/plugins/emitters/redirects.ts, enregistrĂ© dans quartz/plugins/loader/config-loader.ts).

La mĂȘme mise Ă  jour du cƓur Quartz a aussi changĂ© les liens CSS/JS gĂ©nĂ©rĂ©s, de relatifs Ă  absolus (/component-styles.css). Le site est donc un peu moins fragile qu’avant sur ce genre de souci de profondeur d’URL, mĂȘme si _redirects reste nĂ©cessaire pour les pages elles-mĂȘmes.