Liens Enrichis pour Développeurs Paresseux
Quand je partage un lien de blog sur Twitter ou Slack, il apparaît comme du texte brut. Pas d’image d’aperçu. Juste une URL comme granda.org/en/2026/01/02/claude-code-on-the-go/.
J’avais besoin d’images Open Graph. L’approche standard : créer manuellement une image 1200x630 pour chaque article. C’est fastidieux. J’ai demandé à Claude de l’automatiser.
flowchart LR
Push[git push] --> GHA[GitHub Actions]
GHA --> Hugo[Hugo Server]
GHA --> PW[Playwright]
PW -->|screenshot| Hugo
PW --> IMG[OG Image]
IMG --> Commit[git commit]
Commit --> Deploy[Deploy]
flowchart TB
Push[git push] --> GHA[GitHub Actions]
GHA --> Hugo[Hugo Server]
GHA --> PW[Playwright]
PW -->|screenshot| Hugo
PW --> IMG[OG Image]
IMG --> Commit[git commit]
Commit --> Deploy[Deploy]
La Configuration
J’ai expliqué le problème à Claude : les articles ont besoin d’images d’aperçu social, mais je ne veux pas les créer manuellement. Capture d’écran du contenu de l’article, enregistrement en tant qu’image OG, mise à jour automatique du frontmatter.
Ce Que Claude A Construit
| Composant | Objectif |
|---|---|
generate-og-image.js | Script Playwright pour capturer les articles |
generate-og-images.yml | GitHub Action déclenchée lors des modifications d’articles |
Modifications de baseof.html | Balises meta og:image conditionnelles |
Le script Playwright lance Chrome headless, navigue vers l’article, force le mode clair, masque l’en-tête et le pied de page, et capture l’écran à 1200x630 :
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({
viewport: { width: 1200, height: 630 },
deviceScaleFactor: 2, // Retina for crisp text
});
// Force light mode, hide nav
await page.evaluate(() => {
document.documentElement.setAttribute("data-theme", "light");
document.querySelector("header").style.display = "none";
document.querySelector("footer").style.display = "none";
});
await page.screenshot({ path: outputPath, type: "png" });
La GitHub Action se déclenche à chaque modification de fichier .en.md, démarre Hugo, exécute le script et commit l’image générée dans le dépôt :
on:
push:
branches: [main]
paths:
- "content/posts/**/*.md"
steps:
- name: Start Hugo server
run: hugo server --bind 0.0.0.0 --port 1313 &
- name: Generate OG images
run: node scripts/generate-og-image.js "$file"
- name: Commit changes
run: |
git add static/images/posts/ content/posts/
git commit -m "Generate Open Graph images for blog posts"
git push
Le template inclut conditionnellement l’image lorsque le frontmatter a un champ image :
{{- if .Params.image -}}
<meta property="og:image" content="{{ $canonical }}{{ .Params.image }}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="{{ $canonical }}{{ .Params.image }}">
{{- else -}}
<meta name="twitter:card" content="summary">
{{- end -}}
404 : Slug Introuvable
Première exécution. Playwright a capturé une page vide. L’URL retournait 404.
Le script avait construit l’URL à partir du nom de fichier : automatic-blog-translations.en.md → /en/2025/12/23/automatic-blog-translations/
Mais Hugo n’utilise pas le nom de fichier pour les slugs. Il utilise le titre. L’URL réelle était /en/2025/12/23/automatic-blog-translations-with-claude-and-github-actions/.
J’aurais pu réimplémenter l’algorithme slugify de Hugo en JavaScript. À la place : demander à Hugo.
const output = execSync("hugo list all", { encoding: "utf8" });
// CSV output includes the exact permalink Hugo generates
Une ligne. Pas de cas particuliers. Hugo connaît déjà ses propres URLs.
La Suite
L’implémentation actuelle ne génère des images que pour les articles en anglais. Les versions traduites référencent le même chemin d’image, ce qui fonctionne, mais cela signifie que l’image OG affiche toujours du texte anglais même lors du partage d’une version espagnole ou japonaise.
Un vrai support i18n arrive dans la prochaine PR. Pour l’instant, chaque article obtient une image sociale, ce qui est mieux que rien.
La Leçon
Cela a pris 14 minutes à construire et déboguer. Maintenant chaque article obtient automatiquement une image d’aperçu social. Pas de travail manuel par article. L’automatisation est rentabilisée après une poignée d’articles.
Livrez la version fonctionnelle, découvrez les lacunes, itérez.
Articles connexes :
- Traductions Automatiques de Blog avec Claude et GitHub Actions - même stack, automatisation différente
- Mon Ingénieur QA est un LLM - laisser Claude réviser le code qu’il écrit
- Créer Ma Propre Newsletter avec Claude - une autre construction de 30 minutes