Migration de mon site web vers Hugo
J’ai une prédilection pour les sites statiques. Leur sobriété me séduit. Ils présentent par conception une surface d’attaque réduite et s’avèrent plus légers que ceux servis par les CMS. N’étant pas masochiste au point d’écrire moi-même toutes les pages en HTML, je confie leur création à un générateur de site statique. En 2015, j’avais jeté mon dévolu sur Jekyll pour créer mon nouveau site web et celui du projet libre Orekit. Onze ans plus tard, j’ai accumulé assez de frustration pour me lancer dans la migration de mon site vers Hugo.
Pourquoi Hugo ?
Il existe aujourd’hui des centaines de générateurs de site statique. Si la plupart ont une audience confidentielle, certains ont réussi à percer. C’est le cas de Jekyll, Pelican, Docusaurus, Next.js, Zola et d’Hugo. Je n’ai pas procédé à une étude comparative poussée de ces solutions. Je me suis simplement fié à mon instinct et à quelques signes qui ne trompent pas. J’ai écarté Pelican car, à l’instar de Jekyll, ce projet se meurt lentement. J’ai rapidement évalué Docusaurus. Sa versatilité est impressionnante, mais il se révèle lourd et je goute peu l’écosystème Node.js. Zola, outil développé en Rust, se veut d’une vitesse fulgurante et semble promis à un bel avenir. Pourtant, je n’en entends pas souvent parler, ce qui me laisse craindre une base d’utilisateurs réduite.
Hugo n’a aucun de ces travers. C’est un outil mature, dont le développement reste florissant. Il dispose d’une très large communauté. Il est performant et très bien documenté. Hugo n’est pas sans défaut, mais il laisse une grande liberté à ses utilisateurs, qui peuvent organiser leur site comme ils l’entendent. Un autre atout majeur d’Hugo est sa simplicité de déploiement et de mise en œuvre. Cela me change de Jekyll, qui requiert un environnement Ruby lourd et capricieux. Je l’ai cassé plus d’une fois au détour d’une mise à jour du système (il gagne donc à être utilisé via un conteneur qui, dans le cas de Jekyll, apporte son lot de problèmes).
La migration
Mon choix étant fait, il ne me restait plus qu’à trouver le temps que demande un tel chantier et à me retrousser les manches. En 2026, d’aucuns auraient confié cette migration à une IA, j’y reviendrai. Pour ma part, j’aime maitriser mes outils. Je tenais à comprendre le fonctionnement d’Hugo pour l’utiliser correctement et construire une base soutenable.
Un outil et du contenu ne suffisent pas à créer un site. Il faut ensuite donner forme aux pages, les habiller. Intéressé par un rafraichissement de mon site, j’ai évalué plusieurs thèmes libres pour Hugo. Pour diverses raisons, majoritairement subjectives, aucun ne m’a totalement convaincu. J’ai donc conservé et adapté le thème que j’avais créé pour Jekyll en m’appuyant sur le canevas Bootstrap et le thème Slate de Bootswatch. Je reconsidèrerai sans doute cet aspect d’ici quelques temps.
Hugo intègre une fonction d’import de site Jekyll. J’ai cru qu’elle allait me faire gagner beaucoup de temps, mais le résultat a été très décevant, me laissant au milieu du gué et pas forcément sur la bonne voie. J’ai renoncé à l’utiliser et je suis parti d’un squelette vide.
Ne connaissant ni Hugo, ni Go, la prise en main de l’outil n’a pas été une évidence. J’ai parfois buté sur des points triviaux, tel le formatage des dates1. J’ai toujours fini par trouver la réponse à mes questions dans l’abondante documentation du projet, sur son forum ou dans les nombreux articles tiers disponibles sur le net. Je m’étais fixé comme objectif de conserver les URL existantes afin de ne pas saborder le maigre référencement de mon site. C’est sans doute l’un des points qui m’a valu le plus de souci, car Hugo et Jekyll ont une logique interne sensiblement différente. Je suis parvenu à mes fins. Cette cogitation a cependant introduit le doute en moi. Devais-je ou non conserver ce que Hugo appelle les ugly URL ? Autrement dit, devais-je conserver la forme historique des URL, se terminant par un nom de fichier et son extension, ou adopter la forme d’un répertoire désormais privilégiée par la plupart des sites ?
https://www.palabritudes.net/apropos.htmlhttps://www.palabritudes.net/apropos/
Si la seconde est plus compacte et masque la technologie sous-jacente (HTML brut, PHP, ASP, etc.), j’ai choisi la continuité, sans écarter définitivement la seconde option.
Il m’aura fallu une cinquantaine d’heures de travail pour comprendre le fonctionnement d’Hugo, adapter les sources de mes pages, obtenir un rendu identique à celui du site généré par Jekyll et migrer le pipeline de CI/CD (le déploiement de mon site est en effet automatisé et je dispose même d’un environnement de validation). J’ai bien entendu publié les sources de tout cela sous licence libre sur ma forge personnelle.
Quid de l’IA ?
Nous sommes en 2026, ère du vibe coding, des IA génératives et agentiques. Pourquoi ne pas avoir demandé à l’une d’entre elles de faire le travail pour moi ? Au-delà des considérations environnementales, écologiques et sociétales qui m’amènent à réellement m’interroger sur le tsunami que constitue l’IA, j’aime maitriser mes outils. Quand on demande à un tiers de faire, on ne fait pas soi-même. On n’apprend donc pas, et on ne comprend ni le résultat final, ni le chemin qui y a conduit. On perd en maitrise ce que l’on gagne en confort. Je m’en accommode fort bien dans les domaines pour lesquels je n’ai aucune appétence, la mécanique automobile par exemple. Étant informaticien, j’ai une position radicalement différente envers les outils numériques.
Ceci étant, j’étais curieux de juger sur pièce, de comparer ce que j’avais fait à ce qu’aurait fait une IA. J’ai donc demandé à GitHub Copilot de migrer mon site de Jekyll vers Hugo en lui fournissant des consignes précises, telle la conservation des URL. Je lui ai pointé le dépôt Git et le site en ligne. Je lui ai demandé de préserver le rendu. Je lui ai fourni toutes les informations qui me semblaient utiles et que l’IA pouvait rater. Copilot a mouliné pendant une demi-heure et il m’a proposé un premier jet, loin du compte. J’ai relevé les défauts un par un, lui demandant de les corriger. Trois heures et demie et une trentaine d’itérations plus tard, j’avais un résultat presque satisfaisant, mais j’ai senti que l’IA commençait à vriller. À chaque demande d’ajustement, elle anticipait mal les effets de bord des modifications qu’elle effectuait et introduisait des régressions. J’ai donc arrêté là l’expérimentation. Le résultat ne paraissait pas si mauvais à première vue.
Trois heures trente contre cinquante, l’affaire semble entendue… Oui, mais non. Au-delà des imperfections résiduelles, en mettant mon nez dans le code généré par Copilot, j’ai découvert que l’IA n’avait pas intégré le fonctionnement d’Hugo et ne s’en était pas imprégnée. Elle lui avait tordu le bras pour reproduire l’existant et avait créé un château de cartes, une base difficile à maintenir. Même la création de nouveaux articles s’en trouvait compliquée. Tout m’a semblé bon à jeter, à l’exception de deux points :
-
La gestion des tags via les taxonomies (concept fourni par Hugo). J’étais passé à côté et j’avais trouvé une solution bancale, peu satisfaisante.
-
Une façon plutôt élégante – jurant presque dans le grand fatras qu’était le reste du code – d’adresser un autre besoin.
J’ai adopté et intégré les deux. GitHub Copilot n’aura pas tourné pour rien.
Cette expérience a renforcé ma tempérance vis-à-vis de l’IA. Comme le répète l’un de mes collègues, une IA est un stagiaire stakhanoviste, qui manque d’expérience et de recul. Il faut systématiquement contrôler son travail et bien souvent lui demander de l’amender en lui fournissant des directives strictes. On pourrait croire que le problème se situe du côté de l’humain et de son incapacité à fournir des spécifications claires et complètes. La réalité me semble un iota plus complexe.
Quoi qu’il en soit, ce site est désormais généré par Hugo et j’en suis ravi.
-
J’ai mis un moment à comprendre que la date que je voyais dans tous les exemples n’était pas prise au hasard, mais constituait au contraire la convention qui permettait à Go de comprendre le formatage attendu. Pourquoi les auteurs de Go n’ont-ils pas adopté le système en vigueur dans la plupart des autres langages ? ↩︎