Rijke Links voor Luie Ontwikkelaars

Wanneer ik een bloglink deel op Twitter of Slack, verschijnt het als platte tekst. Geen voorbeeldafbeelding. Gewoon een URL zoals granda.org/en/2026/01/02/claude-code-on-the-go/.

Ik had Open Graph afbeeldingen nodig. De standaard aanpak: handmatig een 1200x630 afbeelding maken voor elk bericht. Dat is saai. Ik vroeg Claude om het te automatiseren.

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]

De Opzet

Ik vertelde Claude het probleem: berichten hebben sociale voorbeeldafbeeldingen nodig, maar ik wil ze niet handmatig maken. Maak een screenshot van de artikelinhoud, sla het op als een OG-afbeelding, update de frontmatter automatisch.

Wat Claude Bouwde

ComponentDoel
generate-og-image.jsPlaywright script om berichten te screenshotten
generate-og-images.ymlGitHub Action geactiveerd bij berichtwijzigingen
baseof.html wijzigingenVoorwaardelijke og:image meta tags

Het Playwright script start headless Chrome, navigeert naar het bericht, forceert lichte modus, verbergt de header en footer, en maakt een screenshot op 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" });

De GitHub Action wordt geactiveerd bij elke .en.md bestandswijziging, start Hugo, voert het script uit, en commit de gegenereerde afbeelding terug naar de 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

De template bevat voorwaardelijk de afbeelding wanneer de frontmatter een image veld heeft:

{{- 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 Niet Gevonden

Eerste run. Playwright maakte een screenshot van een lege pagina. De URL gaf 404 terug.

Het script had de URL opgebouwd uit de bestandsnaam: automatic-blog-translations.en.md/en/2025/12/23/automatic-blog-translations/

Maar Hugo gebruikt de bestandsnaam niet voor slugs. Het gebruikt de titel. De werkelijke URL was /en/2025/12/23/automatic-blog-translations-with-claude-and-github-actions/.

Ik had Hugo’s slugify algoritme kunnen herimplementeren in JavaScript. In plaats daarvan: vraag het aan Hugo.

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

Eén regel. Geen randgevallen. Hugo kent zijn eigen URLs al.

Wat Volgt

De huidige implementatie genereert alleen afbeeldingen voor Engelse berichten. Vertaalde versies verwijzen naar hetzelfde afbeeldingspad, wat werkt, maar het betekent dat de OG-afbeelding altijd Engelse tekst toont, zelfs bij het delen van een Spaanse of Japanse versie.

Echte i18n ondersteuning komt in de volgende PR. Voor nu krijgt elk bericht een sociale afbeelding, wat beter is dan geen.

De Conclusie

Dit duurde 14 minuten om te bouwen en te debuggen. Nu krijgt elk bericht automatisch een sociale voorbeeldafbeelding. Geen handmatig werk per bericht. De automatisering betaalt zichzelf terug na een handvol berichten.

Ship de werkende versie, ontdek de hiaten, itereer.


Gerelateerde berichten: