From 1e8192d3fbf3d5bde25867665a9ccd2e5ba13b81 Mon Sep 17 00:00:00 2001 From: Yasutake Yohei <61961825+yasutakeyohei@users.noreply.github.com> Date: Thu, 25 Jun 2026 23:51:28 +0900 Subject: ページごとに異なるOGP画像を自動設定するインテグレーションを追加 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - src/plugins/og-image.ts: ビルド後のHTMLにページ別og:imageを注入 - 各ページのスラッグから /og/{slug}.png 形式でOGP画像URLを生成 - 例: /whisper-to-ai-moji-okoshi/ → /og/whisper-to-ai-moji-okoshi.png --- src/plugins/og-image.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/plugins/og-image.ts (limited to 'src/plugins/og-image.ts') diff --git a/src/plugins/og-image.ts b/src/plugins/og-image.ts new file mode 100644 index 0000000..0cfcbc2 --- /dev/null +++ b/src/plugins/og-image.ts @@ -0,0 +1,40 @@ +import type { AstroIntegration } from "astro"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +/** + * Post-process built HTML files to set per-page og:image. + * Replaces the default og:image with a page-specific one based on URL path. + */ +export default function ogImageIntegration(): AstroIntegration { + return { + name: "og-image-per-page", + hooks: { + "astro:build:done": async ({ dir, pages }) => { + const distDir = typeof dir === "string" ? dir : fileURLToPath(dir); + + for (const page of pages) { + const htmlPath = path.join(distDir, page.pathname, "index.html"); + + if (!fs.existsSync(htmlPath)) continue; + + let html = fs.readFileSync(htmlPath, "utf-8"); + + // Derive slug from pathname: e.g., "/whisper-to-ai-moji-okoshi/" → "whisper-to-ai-moji-okoshi" + let slug = page.pathname.replace(/^\/|\/$/g, "") || "index"; + + const ogImageUrl = `https://yasutakeyohei.com/og/${slug}.png`; + + // Replace existing og:image with page-specific one + html = html.replace( + /