Link Ricchi per Sviluppatori Pigri

Quando condivido un link del blog su Twitter o Slack, appare come testo semplice. Nessuna immagine di anteprima. Solo un URL come granda.org/en/2026/01/02/claude-code-on-the-go/.

Avevo bisogno di immagini Open Graph. L’approccio standard: creare manualmente un’immagine 1200x630 per ogni post. È noioso. Ho chiesto a Claude di automatizzarlo.

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 Configurazione

Ho spiegato il problema a Claude: i post hanno bisogno di immagini di anteprima social, ma non voglio crearle manualmente. Cattura uno screenshot del contenuto dell’articolo, salvalo come immagine OG, aggiorna automaticamente il frontmatter.

Cosa Ha Costruito Claude

ComponenteScopo
generate-og-image.jsScript Playwright per catturare schermate dei post
generate-og-images.ymlGitHub Action attivata dalle modifiche ai post
Modifiche a baseof.htmlTag meta og:image condizionali

Lo script Playwright avvia Chrome headless, naviga al post, forza la modalità chiara, nasconde header e footer, e cattura lo schermo a 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 si attiva ad ogni modifica di file .en.md, avvia Hugo, esegue lo script e fa il commit dell’immagine generata nel repo:

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

Il template include condizionalmente l’immagine quando il frontmatter ha un campo 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 Non Trovato

Prima esecuzione. Playwright ha catturato una pagina vuota. L’URL restituiva 404.

Lo script aveva costruito l’URL dal nome del file: automatic-blog-translations.en.md/en/2025/12/23/automatic-blog-translations/

Ma Hugo non usa il nome del file per gli slug. Usa il titolo. L’URL effettivo era /en/2025/12/23/automatic-blog-translations-with-claude-and-github-actions/.

Avrei potuto reimplementare l’algoritmo slugify di Hugo in JavaScript. Invece: chiedere a Hugo.

const output = execSync("hugo list all", { encoding: "utf8" });
// CSV output includes the exact permalink Hugo generates

Una riga. Nessun caso limite. Hugo conosce già i propri URL.

Cosa Verrà Dopo

L’implementazione attuale genera immagini solo per i post in inglese. Le versioni tradotte fanno riferimento allo stesso percorso dell’immagine, che funziona, ma significa che l’immagine OG mostra sempre testo inglese anche quando si condivide una versione spagnola o giapponese.

Il vero supporto i18n arriverà nella prossima PR. Per ora, ogni post ottiene un’immagine social, che è meglio di niente.

La Lezione

Questo ha richiesto 14 minuti per costruire e debuggare. Ora ogni post ottiene automaticamente un’immagine di anteprima social. Nessun lavoro manuale per post. L’automazione si ripaga da sola dopo una manciata di post.

Rilascia la versione funzionante, scopri le lacune, itera.


Post correlati: