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 --- astro.config.mjs | 2 ++ src/plugins/og-image.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/plugins/og-image.ts diff --git a/astro.config.mjs b/astro.config.mjs index c4f741f..cdf4b20 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,6 +2,7 @@ import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; import sitemap from "@astrojs/sitemap"; import remarkMermaid from "remark-mermaidjs"; +import ogImagePlugin from "./src/plugins/og-image"; export default defineConfig({ site: "https://yasutakeyohei.com", @@ -12,6 +13,7 @@ export default defineConfig({ }, integrations: [ sitemap(), + ogImagePlugin(), starlight({ title: "小平市議 安竹洋平 公式サイト", description: 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( + /