懒惰开发者的富链接
当我在Twitter或Slack上分享博客链接时,它显示为纯文本。没有预览图片。只有一个像granda.org/en/2026/01/02/claude-code-on-the-go/这样的URL。
我需要Open Graph图片。标准方法:为每篇文章手动创建一个1200x630的图片。这很繁琐。我让Claude自动化它。
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]
设置
我向Claude说明了问题:文章需要社交预览图片,但我不想手动创建它们。截取文章内容的屏幕截图,将其保存为OG图片,自动更新前置元数据。
Claude构建了什么
| 组件 | 用途 |
|---|---|
generate-og-image.js | 用于截图文章的Playwright脚本 |
generate-og-images.yml | 文章更改时触发的GitHub Action |
baseof.html更改 | 条件性og:image元标签 |
Playwright脚本启动无头Chrome,导航到文章,强制浅色模式,隐藏页眉和页脚,并以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" });
GitHub Action在任何.en.md文件更改时触发,启动Hugo,运行脚本,并将生成的图片提交回仓库:
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
当前置元数据有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
第一次运行。Playwright截取了一个空白页面。URL返回404。
脚本从文件名构建了URL:automatic-blog-translations.en.md → /en/2025/12/23/automatic-blog-translations/
但Hugo不使用文件名作为slug。它使用标题。实际的URL是/en/2025/12/23/automatic-blog-translations-with-claude-and-github-actions/。
我本可以在JavaScript中重新实现Hugo的slugify算法。相反:询问Hugo。
const output = execSync("hugo list all", { encoding: "utf8" });
// CSV output includes the exact permalink Hugo generates
一行代码。没有边缘情况。Hugo已经知道自己的URL。
接下来是什么
当前实现仅为英文文章生成图片。翻译版本引用相同的图片路径,这是可行的,但这意味着即使在分享西班牙语或日语版本时,OG图片也始终显示英文文本。
真正的i18n支持将在下一个PR中到来。目前,每篇文章都获得一个社交图片,这总比没有好。
总结
这花了14分钟来构建和调试。现在每篇文章都自动获得社交预览图片。每篇文章无需手动工作。自动化在几篇文章后就能收回成本。
发布可用版本,发现差距,迭代。
相关文章:
- 使用Claude和GitHub Actions自动翻译博客 - 相同的技术栈,不同的自动化
- 我的QA工程师是一个LLM - 让Claude审查它编写的代码
- 使用Claude创建我自己的新闻通讯 - 另一个30分钟构建