P PasteCode
Prompt

Prompt zum Generieren von OG-Bildern zur Build-Zeit

KI-Agent-Prompt zum Generieren von pro-Seite Open Graph-Bildern zur Build-Zeit in Astro oder Next.js mit Satori und sharp, ohne externen Dienst.

CursorClaude CodeCodexWindsurf AstroNext.jsTypeScript
.md .json Schwierigkeit: Mittel Aktualisiert 8. Juni 2026

Geben Sie diesen Prompt an Ihren Agenten, um ein eindeutiges OG-Bild-PNG für jede Seite zur Build-Zeit mit Satori und sharp zu generieren – und so die Latenz und Kosten von Laufzeit-OG-Bilddiensten wie Vercel OG zu vermeiden.

Haupt-Prompt

Main Prompt
You are working in an existing Astro 5 static site with TypeScript.
Task: generate a static Open Graph PNG image for every blog post at build time.
Requirements:
- Install `satori` and `sharp`.
- Create `src/lib/generate-og.ts` that exports `generateOgImage({ title, description }: OgData): Promise<Buffer>`.
- Use Satori to render a JSX template (800 x 420 px) with: site name top-left, post title
(large, bold, white), description (smaller, gray), a solid dark background (#0f172a).
- Convert the Satori SVG output to PNG using `sharp(Buffer.from(svg)).png().toBuffer()`.
- Use only system-safe fonts or load `src/fonts/Inter-Bold.ttf` (create a note to add the file).
- Create `src/pages/og/[slug].png.ts` as an Astro endpoint:
- `getStaticPaths`: call `getCollection('blog')` and return a path per post.
- `GET`: call `generateOgImage` with the post's title and description, set
`Content-Type: image/png`, return the buffer.
- In the blog post layout, set `<meta property="og:image" content={ogImageUrl} />` where
`ogImageUrl` is constructed as `/og/${post.slug}.png`.
- Do NOT use `@vercel/og`, `next/og`, or any cloud image generation service.
- Do NOT use Canvas or puppeteer.
Stop and list all planned file changes before writing any code.

Implementierungshinweise

  • Satori akzeptiert JSX-ähnliche Objekte (React-Element-Syntax), verwendet aber NICHT die React-Laufzeit. Übergeben Sie das Element als einfachen Objektbaum direkt mit dem ersten Argument von satori.
  • Schriftarten laden: Satori erfordert mindestens eine Schriftart. Verwenden Sie fs.readFileSync, um die .ttf-Datei zur Build-Zeit zu laden – das ist in einem statischen Astro-Build in Ordnung.
  • Die generierten PNGs befinden sich nach astro build im Ordner dist/og/. Überprüfen Sie ihre Größe; bei 800x420 sollten sie unter 100 KB pro Stück sein, wenn ein einfarbiger Hintergrund verwendet wird.
  • Für Next.js anstelle von Astro: Verwenden Sie einen Route-Handler unter app/og/[slug]/route.ts und rufen Sie NextResponse mit dem PNG-Puffer auf.

Erwartete Dateiänderungen

src/lib/generate-og.ts (new)
src/pages/og/[slug].png.ts (new — Astro endpoint)
src/layouts/BlogPost.astro (edited — add og:image meta)
src/fonts/Inter-Bold.ttf (add manually — not auto-generated)
package.json (edited — add satori, sharp)

Akzeptanzkriterien

  • astro build generiert eine .png-Datei unter dist/og/ für jeden Blogbeitrag.
  • Jedes PNG ist 800 x 420 Pixel groß.
  • Das Blogbeitrags-Layout enthält og:image, das auf den korrekten Pfad /og/<slug>.png verweist.
  • Das Öffnen der OG-Bild-URL in einem Browser zeigt eine gestaltete Karte mit dem Beitragstitel.

Testbefehle

Terminal window
bun add satori sharp
bun run build
ls dist/og/
file dist/og/my-first-post.png # should output "PNG image data, 800 x 420"
curl -I http://localhost:4321/og/my-first-post.png | grep content-type

Häufige KI-Fehler

  • React importieren und versuchen, mit ReactDOMServer zu rendern – Satori verwendet Reacts Laufzeit nicht.
  • Vergessen, eine Schriftart zu laden, was dazu führt, dass Satori "No font found for the first character" wirft.
  • Setzen von og:image auf einen relativen Pfad wie ./og/slug.png – es muss eine absolute URL in der Produktion sein.
  • Verwendung des canvas-Pakets, das native Bindungen erfordert, die mit vielen CI-Umgebungen inkompatibel sind.

Reparatur-Prompt

Fix Prompt
Satori throws a font error or the PNG is blank. Fix in order:
1. Add font loading: `const fontData = fs.readFileSync('src/fonts/Inter-Bold.ttf'); fonts: [{ name: 'Inter', data: fontData, weight: 700 }]` in the satori call.
2. Make sure the JSX-like element passed to satori is a plain object, not a JSX expression — call `satori(element, options)` directly.
3. For the og:image meta tag, use an absolute URL: `const base = import.meta.env.SITE; ogImageUrl = new URL(\`/og/\${slug}.png\`, base).toString();`
Show only the corrected diff.