Migrer de WordPress vers Hugo en 2025 : le guide complet

Quitter WordPress pour Hugo, c’est troquer la richesse d’un CMS contre la vitesse et la simplicité d’un site statique. Retour d’expérience sur cette transition.

Cet article prend 16 minutes à lire et comporte 3802 mots.

Ce n’est un secret pour per­sonne, je suis comme tout blo­gueur et comme tout pro­prié­taire de site obsé­dé par la rapi­di­té de char­ge­ment des pages des mes sites. Et le moins qu’on puisse dire, c’est que Word­Press ne faci­lite pas les choses.

Entre PHP qui génère ses pages à la volée, les appels à la base de don­nées et les plu­gins… sans cache point de salut, et avec un cache, tout n’est pas gagné pour autant. 

Bon, je ne vais pas te men­tir, j’ai réus­si à opti­mi­ser mon site, grâce à Open­Li­teS­peed (voir l’ar­ticle Confi­gu­rer un VPS avec Open­Li­teS­peed et LiteS­peed Cache sur tsw​.ovh, mon blog spé­cial Word­Press) et en optant pour un VPS d’en­trée de gamme per­for­mant – celui de chez Layer7 que je teste dans l’ar­ticle VPS low cost : Layer7 vs Conta­bo. Alors…

Pourquoi tenter l’aventure Hugo ?

Mon site a beau être rapide, je sais aus­si que chaque dixième de seconde gra­pillé est essen­tiel pour le réfé­ren­ce­ment et sur­tout pour mes lec­teurs. Un site lent, c’est l’as­su­rance de perdre 50% des lec­teurs avant même leur arri­vée sur la page. Alors voi­la, j’ai enten­du par­ler de Hugo, et je me suis dit : pour­quoi pas ?

Pour autant, quand on a long­temps uti­li­sé Word­Press, l’idée de tout cas­ser pour repar­tir sur Hugo peut don­ner des sueurs froides. Tu tombes sur des articles de blo­gueurs qui ont ten­té l’expérience… et qui en sont reve­nus dépi­tés : pro­blèmes de migra­tion, images per­dues, liens cas­sés. Bref, de quoi hésiter.

Pour­tant, si comme moi tu rêves d’un site rapide comme l’éclair, sans main­te­nance lourde, sécu­ri­sé par défaut (pas de base SQL ni de plu­gins à pat­cher tous les 15 jours), Hugo est une évi­dence. Et je ne suis pas du genre à me lais­ser arrê­ter par quelques expé­riences ratées. Quand j’ai déci­dé de tes­ter, je fonce – et voi­ci le tuto que j’aurais aimé trouver.

Prérequis

  • Niveau tech­nique : Ce guide s’a­dresse à des uti­li­sa­teurs ayant des bases en ligne de com­mande Linux
  • Accès ser­veur : Vous devez avoir accès root/sudo à un ser­veur Ubuntu/Debian
  • Connais­sances mini­males : Notions de base en édi­tion de fichiers (nano/vim) et navi­ga­tion système
  • Temps esti­mé : Comp­tez 2 à 3 heures pour une migra­tion complète

Avant de commencer : Hugo en quelques mots

Avant de plon­ger dans l’installation et la migra­tion, il est utile de com­prendre com­ment Hugo fonctionne :

  • Hugo est un géné­ra­teur de site sta­tique : il prend tes conte­nus au for­mat Mark­down (.md) et les trans­forme en pages HTML. Dif­fé­rence clé : Word­Press génère les pages à chaque visite (dyna­mique), Hugo les pré-génère une fois (sta­tique). Résul­tat : vitesse maxi­male mais pas de com­men­taires natifs, de recherche ou d’ad­min web.
  • La logique repose sur deux piliers : 
    • Content/ : c’est ton réper­toire d’articles et de pages, chaque fichier .md contient un front mat­ter (méta­don­nées : titre, date, etc.) et le corps en Markdown.
    • Layouts/ et Themes/ : ce sont les gaba­rits (tem­plates). Hugo assemble ton conte­nu .md avec ces tem­plates pour géné­rer le HTML final.
  • Les shortcodes sont des petits mor­ceaux de code réuti­li­sables (par exemple pour gérer les images, inté­grer une vidéo, etc.) – exac­te­ment comme dans Word­Press. [‌gallery‌] devient {{gallery}}.
  • Enfin, static/ contient tous les fichiers ser­vis tels quels (images, CSS, JS).

En résu­mé : tu écris en Mark­down, Hugo s’occupe de la mise en forme et génère un site sta­tique prêt à héber­ger partout.

Structure type d’un projet Hugo

Quand tu crées un site avec hugo new site monsite, tu obtiens quelque chose comme :

monsite/
├── archetypes/        # modèles de front matter pour les nouveaux contenus
├── content/           # tes articles et pages en Markdown (.md)
│   └── posts/
│       └── mon-article.md
├── layouts/           # gabarits personnalisés (templates)
├── static/            # fichiers statiques servis tels quels (images, css…)
├── themes/            # thèmes externes (ex : Hextra)
├── config.toml        # configuration du site (ou .yaml / .json)

Rédiger en Markdown

Chaque fichier .md com­mence par un bloc front mat­ter. Le front mat­ter, c’est l’en-tête de chaque article en YAML (entre les ---) qui contient les méta­don­nées : titre, date, caté­go­ries… Exac­te­ment comme les champs per­son­na­li­sés de Word­Press, mais en plus simple :

---
title: "Exemple"
slug: exemple
date: 2025-08-20 12:00:00
draft: false
categories:
  - "Intelligence artificielle"
tags:
  - "C#"
  - "Python:tips"
---

# Titre principal

paragraphe avec du **gras** et de *l'italique*, un lien [mon domaine](https://mondomaine.com)

- un élément dans une liste à puces
- un deuxième élément dans la liste

> une citation

Quels éditeurs Markdown utiliser ?

  • Visual Stu­dio Code avec l’extension Mark­down All in One (pré­vi­sua­li­sa­tion intégrée).
  • Obsi­dian : par­fait si tu aimes orga­ni­ser tes notes comme un wiki.
  • Dillin­ger : édi­teur WYSIWYG en ligne, avec des capa­ci­tés d’ex­port avan­cées (Mark­down, PDF, HTML).
  • Même un simple édi­teur de texte (nano, vim, note­pad++) suf­fit : Hugo se fiche de l’outil tant que le fichier est en .md.

Installe Hugo Extended

Pour­quoi Exten­ded ? Parce que sans cette ver­sion, impos­sible d’utiliser les thèmes modernes (Sass, pipe­lines d’assets, etc.).

apt remove hugo -y   # si une vieille version traîne
cd /usr/local/bin
wget https://github.com/gohugoio/hugo/releases/latest/download/hugo_extended_0.157.0_Linux-64bit.tar.gz
tar -xzf hugo_extended_0.157.0_Linux-64bit.tar.gz
rm hugo_extended_0.157.0_Linux-64bit.tar.gz

hugo version

Tu dois voir quelque chose comme :

hugo v0.148.2-40c3d8233d4b123eff74725e5766fc6272f0a84d+extended linux/amd64 BuildDate=2025-07-27T12:43:24Z VendorInfo=gohugoio

Hugo est ins­tal­lé, ton envi­ron­ne­ment de tra­vail est prêt…

Crée ton site

Va dans ton dos­sier de tra­vail (par exemple /root/site ou ~/site) et tape :

cd /root/site
hugo new site hugo-hextra
cd hugo-hextra

À ce stade, tu as la struc­ture Hugo de base : content/, themes/, config.toml, etc.
Encore vide, mais prête à accueillir ton futur site.

Ajoute un thème

Pour ce tuto, j’ai opté pour Hex­tra, un thème moderne qui rap­pelle Astra Pro sous Word­Press : rapide, clair, com­plet (c’est d’ailleurs celui que j’u­ti­lise le plus sou­vent avec Word­Press). Il y a tout un ensemble de thèmes que tu peux trou­ver dans les res­sources (en fin d’ar­ticle) ou avec une simple recherche Google.

Il n’y en a pas autant que pour Word­Press, mais il y a déjà de quoi habiller ton site avec un style unique. Et entre nous, la per­son­na­li­sa­tion est bien plus simple qu’a­vec WordPress.

git init
git submodule add https://github.com/imfing/hextra themes/hextra

Puis copie sa config par défaut :

cp themes/hextra/hugo.toml ./hugo.toml

Configure ton site

Édite le fichier hugo.toml et ajoute au moins ces lignes en haut :

baseURL = "http://192.168.1.100/"
title = "Test Hextra sur serveur"
theme = "hextra"

👉 Rem­place 192.168.1.100 par l’IP ou domaine réel de ton serveur.

Lance Hugo sur ton réseau

Pour tes­ter depuis un autre appa­reil du réseau, tape :

hugo server -D --bind=0.0.0.0

Tu dois voir :

Watching for changes in /root/site/{archetypes,assets,content,data,i18n,layouts,static,themes}
Watching for config changes in /root/site/hugo.toml, /root/site/config/_default, /root/site/themes/hextra/config.toml, /root/site/themes/hextra/config/_default
Start building sites …
hugo v0.148.2-40c3d8233d4b123eff74725e5766fc6272f0a84d+extended linux/amd64 BuildDate=2025-07-27T12:43:24Z VendorInfo=gohugoio

                  │ EN
──────────────────┼─────
 Pages            │  49
 Paginator pages  │   0
 Non-page files   │   0
 Static files     │ 235
 Processed images │   0
 Aliases          │  16
 Cleaned          │   0

Built in 293 ms
Environment: "development"
Serving pages from disk
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 0.0.0.0)
Press Ctrl+C to stop

Depuis ton PC ou ton smart­phone sur le même réseau, ouvre :

http://192.168.1.100:1313/

Si tu as une erreur connec­tion refu­sed, ouvre le port côté firewall :

ufw allow 1313/tcp

Importe ton contenu WordPress (script maison, sans wp2hugo)

Ici on suit ma pro­cé­dure : export Word­Press → conver­sion Mark­down via mon script Python. Pas d’outil magique qui décide à ta place.

Les outils magiques, je les ai tes­tés, et très hon­nê­te­ment, ils sont pour beau­coup je pense dans l’in­sa­tis­fac­tion des blo­gueurs qui ont vou­lu poas­ser à Hugo : les plu­gins pour Wor­Press qui te pro­mettent du Mark­down te rendent un Mark­down véro­lé qua­si-inuti­li­sable. Quant à wp2hugo, j’ai fait l’im­passe des­sus pour avoir ce que moi je voulais.

Exporte depuis WordPress

  • Tableau de bord → Outils → Expor­ter → Tous les conte­nus → tu récu­pères un fichier .xml (WXR).
  • Copie ce fichier sur le ser­veur Hugo (ex. /root/wp-export.xml).

Prépare l’environnement de conversion

# Dépendances système
apt update && apt install -y python3 python3-venv python3-pip pandoc

# Dans le dossier du projet Hugo
cd /root/hugo-hextra
python3 -m venv venv-hugo
source venv-hugo/bin/activate
pip install lxml beautifulsoup4 pyyaml

Script de conversion WP → Markdown

Crée tools/wp_xml_to_md.py :

#!/usr/bin/env python3
import os, subprocess, re
from lxml import etree
from datetime import datetime

INPUT_XML = "/root/wp-export.xml"  # chemin vers l’export WXR
OUTPUT_DIR = "content/posts"       # où écrire les .md
os.makedirs(OUTPUT_DIR, exist_ok=True)

NS = {
    "wp": "http://wordpress.org/export/1.2/",
    "content": "http://purl.org/rss/1.0/modules/content/",
}

def to_slug(s):
    return "".join(c.lower() if c.isalnum() or c in "-" else "-" for c in s).strip("-")

def yaml_safe(s: str) -> str:
    """Ajoute des guillemets si nécessaire pour YAML"""
    if re.search(r"[:#\-\?\[\]\{\},&\*!\|>'\"%@`]|^\s|\s$", s) or " " in s:
        return f"\"{s.replace('\"', '\\\"')}\""
    return s

def safe_decode(data: bytes) -> str:
    """Essaie UTF-8 puis fallback en latin-1 → utf-8"""
    try:
        return data.decode("utf-8")
    except UnicodeDecodeError:
        # fallback en latin-1
        return data.decode("latin-1").encode("utf-8").decode("utf-8")

root = etree.parse(INPUT_XML, parser=etree.XMLParser(encoding="utf-8"))

for item in root.xpath("//item"):
    status = item.findtext("{http://wordpress.org/export/1.2/}status") or ""
    post_type = item.findtext("{http://wordpress.org/export/1.2/}post_type") or "post"
    if status != "publish" or post_type not in {"post", "page"}:
        continue

    title = (item.findtext("title") or "Sans titre").strip()
    slug = (item.findtext("{http://wordpress.org/export/1.2/}post_name") or to_slug(title))

    date = (
        item.findtext("{http://wordpress.org/export/1.0/modules/content/}post_date")
        or item.findtext("{http://wordpress.org/export/1.2/}post_date")
        or datetime.utcnow().isoformat()
    )

    html = item.findtext("{http://purl.org/rss/1.0/modules/content/}encoded") or ""

    # Conversion HTML → Markdown via pandoc
    p = subprocess.run(
        ["pandoc", "-f", "html", "-t", "gfm-smart", "--wrap=none"],
        input=html.encode("utf-8"),
        capture_output=True,
    )
    md = safe_decode(p.stdout).strip()

    # Récupération des catégories et tags
    categories = [
        cat.text.strip()
        for cat in item.findall("category")
        if cat.get("domain") == "category" and cat.text
    ]
    tags = [
        cat.text.strip()
        for cat in item.findall("category")
        if cat.get("domain") == "post_tag" and cat.text
    ]

    # Front matter YAML
    fm = [
        "---",
        f'title: "{title.replace("\\", "\\\\").replace("\"", "\\\"")}"',
        f"slug: {slug}",
        f"date: {date}",
        "draft: false",
    ]
    if categories:
        fm.append("categories:")
        for c in categories:
            fm.append(f"  - {yaml_safe(c)}")
    if tags:
        fm.append("tags:")
        for t in tags:
            fm.append(f"  - {yaml_safe(t)}")
    fm.extend(["---", ""])

    out_name = f"{date[:10]}-{slug}.md" if post_type == "post" else f"{slug}.md"

    with open(os.path.join(OUTPUT_DIR, out_name), "w", encoding="utf-8") as f:
        f.write("\n".join(fm) + md + "\n")

print("Conversion terminée →", OUTPUT_DIR)

Exé­cute :

python tools/wp_xml_to_md.py

Tu obtiens des fichiers Mark­down propres dans content/posts/, sans bidouille.

Gére les images (import + conversion AVIF/WebP + shortcode)

Objec­tif : récu­pé­rer tes images Word­Press, les conver­tir en AVIF + WebP (avec fall­back), puis les ser­vir via un short­code Hugo.

Outils requis

Option Python (simple et portable) :

source venv-hugo/bin/activate
pip install requests pillow pillow-avif-plugin
# (selon la distro, prévoir libavif/libaom côté système pour l’AVIF)

Option CLI (rapide et robuste) :

apt install -y libavif-bin webp  # avifenc / cwebp

Télécharge et convertis les images (sans toucher aux .md)

Crée tools/images_fetch_convert.py :

    Ne man­quez plus un article… 

    Abon­nez-vous à la newsletter ! 

    #!/usr/bin/env python3
    import os, re, subprocess, shutil, requests
    from pathlib import Path
    from io import BytesIO
    from PIL import Image
    import pillow_avif  # noqa: F401 (active le support AVIF)
    
    MD_DIR = Path("content")
    OUT_DIR = Path("static/images")
    OUT_DIR.mkdir(parents=True, exist_ok=True)
    
    IMG_MD = re.compile(r'!\[([^\]]*)\]\((https?://[^)]+)\)')
    IMG_HTML = re.compile(r'<img[^>]+src="([^"]+)"[^>]*>', re.I)
    
    
    def save_bytes_as(img_bytes, base_noext):
        # Original (debug)
        with open(base_noext + ".orig", "wb") as f: f.write(img_bytes)
        # Pillow → AVIF/WebP (fallback CLI si besoin)
        try:
            img = Image.open(BytesIO(img_bytes))
            img.save(base_noext + ".avif", "AVIF")
        except Exception:
            if shutil.which("avifenc"):
                tmp = base_noext + ".tmp"
                with open(tmp, "wb") as f: f.write(img_bytes)
                subprocess.run(["avifenc", tmp, base_noext + ".avif"]); os.remove(tmp)
        try:
            img = Image.open(BytesIO(img_bytes))
            img.save(base_noext + ".webp", "WEBP")
        except Exception:
            if shutil.which("cwebp"):
                tmp = base_noext + ".tmp"
                with open(tmp, "wb") as f: f.write(img_bytes)
                subprocess.run(["cwebp", "-q", "80", tmp, "-o", base_noext + ".webp"]); os.remove(tmp)
    
    
    def process_url(url):
        filename = url.split("?")[0].split("/")[-1]
        base = OUT_DIR / Path(filename).name
        base_noext = str(base.with_suffix(''))
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        save_bytes_as(r.content, base_noext)
        print("✔", filename)
    
    for md in MD_DIR.rglob("*.md"):
        text = md.read_text(encoding="utf-8")
        urls = set([u for _, u in IMG_MD.findall(text)] + IMG_HTML.findall(text))
        for u in urls:
            if u.startswith("http"):
                try: process_url(u)
                except Exception as e: print("✖", u, e)
    
    print("Terminé →", OUT_DIR)
    

    Lance :

    python tools/images_fetch_convert.py
    

    Résul­tat : pour chaque image trou­vée, tu obtiens static/images/mon-image.avif, static/images/mon-image.webp et static/images/mon-image.jpg.

    Shortcode img.html (balise <picture> avec fallback)

    Crée layouts/shortcodes/img.html :

    {{ $src := .Get "src" }}
    {{ $alt := .Get "alt" | default "" }}
    <picture>
      <source type="image/avif" srcset="{{ $src }}.avif" />
      <source type="image/webp" srcset="{{ $src }}.webp" />
      <img src="{{ $src }}.jpg" alt="{{ $alt }}" loading="lazy" />
    </picture>
    

    Appel dans tes .md (sans exten­sion) :

    {{< img src="/images/n8n-add-nodes" alt="n8n – ajouter un nœud" >}}
    

    Réécris automatiquement les .md pour remplacer ![]() / <figure> par le shortcode

    Tu as deux options pour com­plé­ter cette étape, tu testes et en fonc­tion du résul­tat, tu choi­sis celle qui donne le meilleur résul­tat sur ton conte­nu. Ou tu adaptes, si aucune ne te convient parfaitement.

    • Ver­sion rapide basée sur regex (Mark­down ![]()) :
    # tools/replace_md_images_with_shortcode.py
    import os, re
    ROOT = "content"
    BASE = "/images"
    pat = re.compile(r'!\[([^\]]*)\]\((https?://[^)]+)\)')
    for root, _, files in os.walk(ROOT):
        for fn in files:
            if not fn.endswith('.md'): continue
            p = os.path.join(root, fn)
            txt = open(p, encoding='utf-8').read()
            def repl(m):
                alt, url = m.group(1), m.group(2)
                name = os.path.basename(url.split('?')[0])
                noext = os.path.splitext(name)[0]
                return f"{{{{< img src=\"{BASE}/{noext}\" alt=\"{alt}\" >}}}}"
            new = pat.sub(repl, txt)
            if new != txt:
                open(p,'w',encoding='utf-8').write(new)
                print('✔', p)
    
    • Ver­sion HTML avec <figure> WordPress :
    # tools/replace_figure_with_shortcode.py
    from bs4 import BeautifulSoup
    import os
    ROOT = "content"
    BASE = "/images"
    for root, _, files in os.walk(ROOT):
        for fn in files:
            if not fn.endswith('.md'): continue
            p = os.path.join(root, fn)
            txt = open(p, encoding='utf-8').read()
            soup = BeautifulSoup(txt, 'html.parser')
            changed = False
            for fig in soup.find_all('figure'):
                img = fig.find('img')
                if not img or not img.get('src'): continue
                url = img['src']
                alt = img.get('alt','')
                name = os.path.basename(url.split('?')[0])
                noext = os.path.splitext(name)[0]
                shortcode = f"{{{{< img src=\"{BASE}/{noext}\" alt=\"{alt}\" >}}}}"
                fig.replace_with(shortcode)
                changed = True
            if changed:
                open(p,'w',encoding='utf-8').write(str(soup))
                print('✔', p)
    

    Déploie ton site statique

    Une fois satis­fait du ren­du, il ne te reste plus qu’à publier ton site :

    hugo
    cp -r public/* /var/www/html/
    

    ✅ Ton site est désor­mais acces­sible en clair via http://192.168.1.16/. Tu n’as plus besoin de Hugo jus­qu’à la pro­chaine mise à jour, tu pour­rais même le dés­ins­tal­ler, ton site res­te­rait visible, tant que tu as un ser­veur web (Apache, NGINX, Cad­dy…) bien configuré.

    Pour déployer ton site sur inter­net, n’ou­blie pas le volet sécu­ri­té : c’est du HTML, d’ac­cord, mais celà ne t’af­fran­chis pas de la ges­tion des cer­ti­fi­cats SSL, et de l’a­jout des en-têtes de sécu­ri­té. Il y a moins de risques qu’a­vec un site dyna­mique, mais le risque zéro n’existe pas.

    Avant la migration : Checklist indispensable

    Avant de te lan­cer dans la migra­tion, il est pri­mor­dial de t’assurer que tu es prêt à toute éven­tua­li­té et que tu n’auras aucune mau­vaise sur­prise. Voi­ci une che­ck­list à res­pec­ter incon­di­tion­nel­le­ment :

    • Backup inté­gral du site et de la base de données
      • Sau­ve­garde tous les fichiers WP (FTP/tar/zip du dos­sier), exports de la base MyS­QL, éven­tuels dos­siers uploads ou custom.
      • Véri­fie la vali­di­té des sau­ve­gardes sur un autre serveur/test : c’est la seule façon de « reve­nir en arrière » sans tout perdre en cas de pépin.
    • Éta­blis un plan pré­cis d’action
      • Quelles redi­rec­tions mettre en place ? (anciens liens → nou­veaux liens Hugo, ges­tion SEO)
      • Quelles fonc­tion­na­li­tés sont per­dues ou changent ? (recherche, for­mu­laires, com­men­taires : faut-il pré­voir Disqus/Remark42, Algolia…)
      • Y a‑t-il des phases tem­po­raires d’in­dis­po­ni­bi­li­té ? Un mes­sage d’info pour les lecteurs ?
    • Bat­te­rie de tests mul­ti-navi­ga­teurs et devices avant mise en production
      • N’attends pas d’être en “prod” pour véri­fier que le nou­veau site s’af­fiche bien sur Chrome, Fire­fox, Ope­ra, Safa­ri, Android, iOS.
      • Véri­fie aus­si la vitesse sur mobile (3G/4G), le res­pon­sive, l’accessibilité visuelle et la navi­ga­tion sans sou­ris (tabu­la­tion, lec­teurs d’écran).
      • Repère bien ce qui dif­fère entre les navi­ga­teurs : la fidé­li­té n’est pas automatique

    Aller plus loin

    Ce guide t’offre une pro­cé­dure clé en main pour une migra­tion propre et sereine, mais il y reste de nom­breuses opti­mi­sa­tions, notam­ment si tu vises la per­for­mance abso­lue ou la ges­tion de gros volumes. Voi­ci quelques points que je n’ai pas abor­dés en détail :

    • Per­for­mance pour les gros sites
      • Uti­li­sa­tion avan­cée de partialCached pour évi­ter les recal­culs inutiles sur des mil­liers de pages.
      • Pro­fi­ter des pipe­lines de cache (Hugo Pipes) pour com­pres­ser / mini­fier / fin­ger­prin­ter / véri­fier l’empreinte des assets CSS et JS.
      • Uti­li­sa­tion de PostCSS pour auto­ma­ti­ser les pré­fixes CSS ou les trans­for­ma­tions avancées.
      • Bund­ler les fichiers pour limi­ter le nombre de requêtes HTTP.
    • Orga­ni­sa­tion opti­male des médias
      • Gérer les images de chaque article via les Page Bundles (dans le même dos­sier que le Mark­down, plus facile pour du mul­ti-for­mat AVIF/WebP).
      • Mettre les images “glo­bales” (logo, favi­cons…) plu­tôt dans assets/medias que dans static/images pour pro­fi­ter des trans­for­ma­tions Hugo Pipes.
    • Work­flow avancé
      • Auto­ma­ti­ser les builds avec CI/CD (Net­li­fy, GitHub Actions, Cle­ver Cloud…) pour déployer sans erreur et pro­fi­ter du cache incrémental.
      • Opti­mi­ser la ges­tion des menus, catégories/tags, et inté­grer un moteur de recherche sta­tique (Lunr, Algolia…).

    Autant de points que j’a­bor­de­rai peut-être dans de pro­chains articles, si j’en ai le temps…

    L’envers du décor – expérimentation, erreurs et blocages…

    Quand on expé­ri­mente, on n’a pas for­cé­ment le résul­tat atten­du au pre­mier essai. Avant de pro­duire ce tuto, j’ai dû tes­ter, ten­ter une approche, une autre, par­fois beau­coup d’autres…

    Alors ne te décou­rage pas si tu rencontres :

    • Erreur try not defined → ta ver­sion de Hugo est trop vieille pour Hex­tra. Mets à jour.
    • 404 en accé­dant à http://IP/ → il faut lan­cer hugo et copier le conte­nu du dos­sier public/ dans /var/www/html/.
    • Impos­sible d’accéder depuis un autre appa­reil → ajoute --bind=0.0.0.0 et ouvre ton firewall.

    Chaque blo­cage est une étape nor­male. Quand tu bloques, cherche une solu­tion, soit via Google, soit en uti­li­sant un assis­tant IA (Claude d’An­thro­pic, ChatGPT, Deep­Seek, Kimi… sont des assis­tants intel­li­gents qui trou­ve­ront une solu­tion à ton blo­cage – et qui te l’expliqueront). 

    Et si tu es arri­vé jusqu’ici, féli­ci­ta­tions : tu as ton Word­Press trans­for­mé en site sta­tique rapide et moderne.

    Le mot de la fin : WordPress ou Hugo pour mon blog ?

    Après tous ces tests et cette ana­lyse appro­fon­die, une ques­tion demeure : vais-je migrer mon propre blog vers Hugo ? La réponse est non, et voi­ci pourquoi.

    Mon site Word­Press actuel, avec sa confi­gu­ra­tion Open­Li­teS­peed et LS Cache, me donne entière satis­fac­tion. Les 329ms de temps de char­ge­ment sur la page d’ac­cueil res­tent excel­lents pour l’ex­pé­rience uti­li­sa­teur, et mon tra­fic actuel (quelques mil­liers de visi­teurs par mois) ne jus­ti­fie pas l’a­ban­don de l’é­co­sys­tème Word­Press. J’y per­drais l’in­ter­face d’ad­mi­nis­tra­tion que j’ap­pré­cie, la flexi­bi­li­té des plu­gins, et sur­tout la sim­pli­ci­té de publi­ca­tion depuis n’im­porte quel appareil.

    Hugo repré­sente une solu­tion remar­quable pour qui pri­vi­lé­gie la per­for­mance pure et accepte les contraintes tech­niques qu’elle impose. Mais pour un blog per­son­nel avec un tra­fic modé­ré, opti­mi­ser Word­Press reste plus prag­ma­tique que de tout recons­truire. Cette expé­ri­men­ta­tion m’a sur­tout confir­mé que le choix de pla­te­forme dépend moins des per­for­mances brutes que de l’a­dé­qua­tion avec ses besoins réels et sa façon de travailler.

    Par­fois, le mieux est l’en­ne­mi du bien. Et dans mon cas, « assez rapide » avec Word­Press vaut mieux que « très rapide » avec Hugo si cela implique de perdre mon confort de publi­ca­tion quo­ti­dien. Même si je suis un fan incon­di­tion­nel de Hugo.

    Par contre, pour chaque nou­veau pro­jet, je me pose­rai for­cé­ment la ques­tion : Word­Press ou Hugo ?

    Ressources

    Pas­cal CESCATO

    Je ne me contente pas de refor­mu­ler des com­mu­ni­qués ou de dérou­ler des specs. Je teste, je creuse, je démonte quand il faut – parce qu’un sujet mal com­pris est un sujet mal écrit. J’écris avec les mains dans le cam­bouis, sans sim­pli­fier à outrance ni recra­cher du mar­ke­ting. Mon truc, c’est de rendre clair sans tra­hir, lisible sans lis­ser. Et non, je ne “fais pas du conte­nu”. Pas pour faire du conte­nu, en tout cas.

    S’abonner
    Notification pour
    guest
    0 Commentaires
    Le plus ancien
    Le plus récent Le plus populaire
    Commentaires en ligne
    Afficher tous les commentaires
    Table des matières
    Retour en haut
    Les cookies que nous utilisons sont indispensables au bon fonctionnement de ce site. Il n'y a aucun pistage publicitaire et les données statistiques recueillies sont anonymisées.
    J'ai compris