Prompt para Gerar Imagens OG no Momento da Build
Prompt para agente de IA gerar imagens Open Graph por página no momento da build em Astro ou Next.js usando Satori e sharp, sem serviço externo.
CursorClaude CodeCodexWindsurf AstroNext.jsTypeScript
Entregue este prompt ao seu agente para gerar uma imagem PNG OG única para cada página no momento da build usando Satori e sharp — evitando a latência e o custo de serviços de imagem OG em tempo de execução como Vercel OG.
Prompt Principal
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.Notas de Implementação
- Satori aceita objetos semelhantes a JSX (sintaxe de elemento React), mas NÃO usa o runtime React.
Passe o elemento como uma árvore de objeto simples usando o primeiro argumento do
satoridiretamente. - Carregamento de fontes: Satori requer pelo menos uma fonte. Use
fs.readFileSyncpara carregar o arquivo.ttfno momento da build — isso é tranquilo em uma build estática do Astro. - Os PNGs gerados estarão na pasta
dist/og/apósastro build. Verifique o tamanho; em 800x420 devem ficar abaixo de 100 KB cada se usando um fundo de cor sólida. - Para Next.js em vez de Astro: use um Route Handler em
app/og/[slug]/route.tse chameNextResponsecom o buffer PNG.
Alterações Esperadas nos Arquivos
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)Critérios de Aceitação
astro buildgera um arquivo.pngdentro dedist/og/para cada post do blog.- Cada PNG tem 800 x 420 pixels.
- O layout do post do blog inclui
og:imageapontando para o caminho correto/og/<slug>.png. - Abrir a URL da imagem OG em um navegador mostra um card estilizado com o título do post.
Comandos de Teste
bun add satori sharpbun run buildls 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-typeErros Comuns de IA
- Importar React e tentar renderizar com
ReactDOMServer— Satori não usa o runtime do React. - Esquecer de carregar uma fonte, o que faz o Satori lançar
"No font found for the first character". - Definir
og:imagepara um caminho relativo como./og/slug.png— deve ser uma URL absoluta em produção. - Usar o pacote
canvasque requer bindings nativos incompatíveis com muitos ambientes de CI.
Prompt de Correção
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.