Faire en sorte que f-l.ca me ressemble
J’utilise vanityURLs depuis 2024. C’est la frontière utile. Le moteur reste ennuyeux et la surface publique gagne de la personnalité.
Pour f-l.ca, je voulais autre chose : un moteur ennuyeux, mais une surface publique qui me ressemble immédiatement.












Pour le chemin mécanique, consultez Marque et Surcharges custom.
L’url est l’interface
Mon thème tourne autour d’une idée simple : le lien lui-même devrait être l’objet principal de la page.
Quand quelqu’un tape un slug, la flèche ronde devient l’action.
Quand un chemin est invalide, l’écran shake et montre le chemin au visiteur au lieu de changer de système visuel.
Le mode custom complet a un coût
Ce n’est pas le chemin le plus rapide, vous pouvez demander à mon co-mainteneur . Le mode custom complet veut dire que l’instance fournit ses propres pages publiques dans custom/public, y compris les variantes anglaises et françaises, les pages de consultation et les pages d’état.
Cela fait de l’internationalisation une partie du travail de thème. Les pages localisées doivent rester équivalentes, pas seulement traduites une fois.
Cela veut aussi dire que le thème doit se comporter comme du code produit :
- les pages anglaises et françaises doivent rester alignées
- toutes les pages doivent garder le même langage visuel que l’accueil
- le HTML custom doit avoir une posture Content Security Policy délibérée
- les fichiers custom doivent éviter les collisions avec les assets livrés par vanityURLs
- les pages opérateur protégées1 comme
_statset_testsdemandent une décision explicite : les personnaliser, ou les laisser au produit
Les pages par défaut de vanityURLs absorbent la majorité de cette maintenance. Un thème custom donne plus de contrôle. Il retire aussi quelques garde-fous.
Garder les noms produit hors des fichiers custom
Une frontière que je ne franchirais pas concerne les noms de fichiers. Cette frontière compte au build.
Les pages custom utilisent des noms comme flstyle.css et flscript.js, parce qu’ils appartiennent à l’instance. Je ne créerais pas de fichiers custom portant les mêmes noms que les assets gérés par le produit dans defaults/public, surtout v8s-style.css, v8s-script.js, v8s-status.css, v8s-lookup.js ou v8s-theme.js.
Le build copie defaults/public d’abord, puis superpose custom/public.2 Si un fichier custom masque un fichier v8s-* géré, les choses deviennent bizarres pendant que les pages qui restent vanilla continuent d’attendre le CSS et le JavaScript par défaut courants.
La séparation est simple : donner leurs propres noms d’assets aux pages web et d’état custom, et laisser les pages qui restent vanilla utiliser les fichiers v8s-* gérés.
C’est une autre frontière de confiance
Au 16 juin 2026, la documentation des pages publiques de vanityURLs indique que le HTML custom reçoit un profil CSP compatible et sandboxé, tandis que le CSS, le JavaScript, les images, les polices et les manifests référencés sont servis comme assets normaux.3
C’est le bon défaut pour des pages copiées ou écrites à la main. Il permet du CSS et du JavaScript même hôte sans accorder la confiance des pages produit.
Il y a un coût. Le JavaScript custom ne devrait pas dépendre des cookies de l’hôte, de localStorage côté hôte, ou d’API same-origin protégées quand le sandbox omet allow-same-origin. Heureusement, vanityURLs n’utilise pas ces capacités.
La marque vit dans les petits choix
Le travail de marque n’est pas le formulaire de slug. Ça, c’est l’interface.
Le travail de marque, c’est la retenue autour : un fond chaud, une URL monospace, une petite marque jaune dans le coin, et presque pas de texte explicatif. La page devrait sembler possédée sans demander à être admirée.
Mon thème supporte les modes clair et sombre, mais il le fait différemment des pages vanityURLs par défaut. J’utilise directement des variables CSS avec prefers-color-scheme dans flstyle.css. C’est suffisant.
Les pages par défaut utilisent le helper produit v8s-theme.js pour que les liens QA puissent forcer les aperçus avec ?theme=light et ?theme=dark; consultez Surcharges custom et Contrôle d’accès quand vous testez les aperçus protégés dans _tests. Vous pouvez voir ci-dessous les liens QA par défaut.

Je n’ai pas personnalisé les pages opérateur : _stats et _tests. Ce ne sont pas des surfaces de marque publiques.
Dire à la maintenance ce qui est intentionnel
Le fichier de maintenance est custom/v8s-custom-overrides.json. vanityURLs utilise ce JSON pour que npm run doctor4 et v8s-fix sachent quelles différences custom ne doivent pas être réparées vers /defaults.
Ce registre compte parce que l’expérience 404 n’est pas un document d’erreur séparé qui ressemble aux pages par défaut. C’est la même surface de redirection. Quand un chemin est introuvable, la page peut afficher le chemin saisi et secouer le formulaire.
Sans ce registre d’override, l’outillage de maintenance doit traiter ces différences comme une dérive possible. Le manifest courant est explicite :
{
"schema_version": "1.0",
"doctor": {
"ignore": [
{
"paths": [
"custom/public/en/404.html",
"custom/public/en/abuse.html",
"custom/public/en/disabled.html",
"custom/public/en/expired.html",
"custom/public/en/index.html",
"custom/public/en/lookup/index.html",
"custom/public/en/maintenance.html",
"custom/public/fr/404.html",
"custom/public/fr/abuse.html",
"custom/public/fr/disabled.html",
"custom/public/fr/expired.html",
"custom/public/fr/index.html",
"custom/public/fr/lookup/index.html",
"custom/public/fr/maintenance.html"
],
"codes": ["html-head-assets-stale", "branding-stale"],
"reason": "Felix intentionally uses a custom single-screen theme, including the home-style 404 fallback."
},
{
"paths": [
"custom/public/android-chrome-192x192.png",
"custom/public/android-chrome-512x512.png",
"custom/public/apple-touch-icon.png",
"custom/public/favicon-16x16.png",
"custom/public/favicon-32x32.png",
"custom/public/favicon.ico",
"custom/public/en/android-chrome-192x192.png",
"custom/public/en/android-chrome-512x512.png",
"custom/public/en/apple-touch-icon.png",
"custom/public/en/favicon-16x16.png",
"custom/public/en/favicon-32x32.png",
"custom/public/en/favicon-48x48.png",
"custom/public/en/favicon.svg",
"custom/public/en/site.webmanifest",
"custom/public/en/v8s-redirected-dark.svg",
"custom/public/en/v8s-redirected.svg",
"custom/public/fonts/intervariable.woff2",
"custom/public/fonts/jetbrainsmono.woff2",
"custom/public/flstyle.css",
"custom/public/fr/v8s-redirected-dark.svg",
"custom/public/fr/v8s-redirected.svg",
"custom/public/_tests/index.html",
"custom/public/icon.png",
"custom/public/logo.png",
"custom/public/logo.svg",
"custom/public/lookup.css",
"custom/public/lookup.js",
"custom/public/flscript.js",
"custom/public/site.webmanifest"
],
"codes": ["shared-asset-stale"],
"reason": "Felix intentionally owns these theme and identity assets."
},
{
"paths": ["custom/public/_tests/index.html"],
"codes": ["product-page-stale"],
"reason": "Felix intentionally uses a themed QA page for the full custom mode test instance."
}
]
}
}
C’est la ligne fine du mode custom complet : documenter les différences que vous voulez posséder, pointer vers la documentation produit pour les défauts sur lesquels vous comptez encore, et laisser l’outillage aider partout ailleurs.
_statsest le tableau de bord protégé en lecture seule;_testsest la matrice de tests runtime protégée. Consultez Lire le tableau admin vanityURLs et Contrôle d’accès. ↩︎Consultez la documentation vanityURLs sur l’internationalisation pour le comportement de build : les assets publics par défaut sont copiés,
custom/publicest superposé, puis les répertoires de langue non supportés sont retirés debuild/. ↩︎Content Security Policy Level 3 était un Working Draft du W3C daté du 5 mai 2026 au moment de préparer cet article. Pour l’implémentation vanityURLs, consultez Approche de sécurité runtime et Pages publiques et pages de statut. Le comportement des pages custom est un détail d’implémentation, pas une exigence CSP. ↩︎
Consultez Pages publiques et pages de statut pour la forme de
doctor.ignore. Pour l’intégrité des assets, consultez W3C Subresource Integrity. ↩︎