Gere imagens Open Graph com uma chamada de API, sem necessidade de Next.js
Use a API de imagem botoi OG para gerar cartões sociais PNG de 1200x630 a partir de qualquer estrutura. Funciona com plataformas Astro, Django, Rails, Laravel e CMS headless.
A postagem do seu blog é compartilhada no Twitter. Em vez de uma visualização detalhada com um cartão de título, o link mostra um caixa cinza em branco. Ou pior, um favicon esticado. Cada compartilhamento sem uma imagem OG adequada é um clique perdido.
A solução popular é a Vercel @vercel/og biblioteca. Funciona bem, mas está bloqueado para
Infraestrutura Next.js e Vercel. Satori (o mecanismo por trás dele) precisa de um tempo de execução Node.js com
recursos de carregamento de fontes. Se você estiver construindo com Astro, Django, Rails, Laravel, Hugo ou qualquer outro
estrutura, você está por conta própria.
Existe uma abordagem mais simples: envie uma solicitação POST para uma API e receba de volta um PNG 1200x630 finalizado. Nenhuma dependência do Node.js. Sem bloqueio de estrutura. Nenhum pipeline de renderização de imagem para manter.
Uma solicitação POST, um PNG de volta
O botoi E API de imagem aceita um corpo JSON com seu título, descrição e preferência de tema. Ele retorna dados binários PNG brutos.
curl -X POST https://api.botoi.com/v1/og/generate \\
-H "Content-Type: application/json" \\
-d '{
"title": "How to build a REST API in Go",
"description": "A step-by-step guide with net/http and no frameworks",
"theme": "dark"
}' \\
--output og-image.png
É isso. A resposta é um arquivo PNG que você pode salvar, veicular ou enviar para um CDN:
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 48271
(binary PNG data, 1200x630px)
A API lida com tipografia, layout e dimensionamento adequado. Você passa o texto e obtém uma imagem.
Integração Astro: gere imagens OG em tempo de construção
A geração de sites estáticos do Astro torna isso especialmente limpo. Crie uma rota de API dinâmica que busque
Imagens OG durante a construção e as serve como estáticas .png arquivos.
// src/pages/og/[slug].png.ts
import type { APIRoute, GetStaticPaths } from 'astro';
// Your posts data source (markdown, CMS, database, etc.)
import { getAllPosts } from '@/lib/posts';
export const getStaticPaths: GetStaticPaths = async () => {
const posts = await getAllPosts();
return posts.map((post) => ({
params: { slug: post.slug },
props: { title: post.title, description: post.description },
}));
};
export const GET: APIRoute = async ({ props }) => {
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: props.title,
description: props.description,
theme: 'dark',
}),
});
const imageBuffer = await res.arrayBuffer();
return new Response(imageBuffer, {
headers: {
'Content-Type': 'image/png',
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
};
Durante astro build, essa rota gera um PNG para cada postagem. Os arquivos de saída chegam em
seu dist/og/ diretório como ativos estáticos. Sem geração de imagens em tempo de execução, sem servidor
função, sem partidas a frio.
Faça referência às imagens no cabeçalho da sua página:
<!-- In your BaseLayout.astro or page head -->
<meta property="og:image" content={\`https://yoursite.com/og/\${slug}.png\`} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content={\`https://yoursite.com/og/\${slug}.png\`} />
Cada página recebe um cartão social exclusivo, gerado uma vez durante a construção e armazenado em cache para sempre pelos CDNs.
Integração Django e Rails
Estruturas renderizadas por servidor podem gerar imagens OG sob demanda e armazenar em cache o resultado.
Django
# views.py
import requests
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
@cache_page(60 * 60 * 24) # Cache for 24 hours
def og_image(request, slug):
post = get_object_or_404(Post, slug=slug)
response = requests.post(
'https://api.botoi.com/v1/og/generate',
json={
'title': post.title,
'description': post.description,
'theme': 'dark',
},
timeout=5,
)
return HttpResponse(
response.content,
content_type='image/png',
)
# urls.py
urlpatterns = [
path('og/<slug:slug>.png', views.og_image, name='og_image'),
]
O @cache_page decorador armazena a imagem gerada por 24 horas. Depois do primeiro
solicitação, o Django serve o PNG armazenado em cache diretamente, sem acessar a API novamente.
Trilhos
# app/controllers/og_images_controller.rb
class OgImagesController < ApplicationController
def show
post = Post.find_by!(slug: params[:slug])
response = HTTP.post(
'https://api.botoi.com/v1/og/generate',
json: {
title: post.title,
description: post.description,
theme: 'dark'
}
)
expires_in 24.hours, public: true
send_data response.body.to_s, type: 'image/png', disposition: 'inline'
end
end
# config/routes.rb
get 'og/:slug.png', to: 'og_images#show'
Ambos os exemplos seguem o mesmo padrão: procure a postagem por slug, POSTE o título e a descrição para a API e retorne o PNG com cabeçalhos de cache. A estrutura lida com o cache; a API trata geração de imagens.
Integração Headless CMS: gerar na publicação
Se o seu conteúdo reside em um CMS sem cabeça como Strapi, Contentful ou Sanity, você pode gerar OG imagens sempre que um editor publica ou atualiza uma postagem. Conecte um webhook que seja acionado no conteúdo mudanças.
Manipulador de webhook genérico
// Webhook handler (any Node.js server or serverless function)
import { writeFileSync } from 'fs';
export async function handleCmsPublish(payload) {
const { title, description, slug } = payload.entry;
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, description, theme: 'light' }),
});
const buffer = Buffer.from(await res.arrayBuffer());
// Save to your public/static directory or upload to S3/R2
writeFileSync(\`./public/og/\${slug}.png\`, buffer);
console.log(\`Generated OG image for: \${slug}\`);
}
Gancho de ciclo de vida Strapi
// Strapi lifecycle hook: src/api/post/content-types/post/lifecycles.js
module.exports = {
async afterUpdate(event) {
const { result } = event;
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: result.title,
description: result.description,
theme: 'dark',
}),
});
// Upload to your CDN or save locally
const buffer = Buffer.from(await res.arrayBuffer());
await strapi.plugins.upload.services.upload.upload({
data: { path: \`og/\${result.slug}.png\` },
files: { buffer, name: \`\${result.slug}.png\`, type: 'image/png' },
});
},
};
Esta abordagem é útil para equipes onde os editores de conteúdo publicam através de um CMS e os desenvolvedores não deseja executar um pipeline de construção para cada alteração de texto. A imagem OG se regenera automaticamente quando o postar alterações no título ou na descrição.
Bônus: extraia metadados OG de qualquer URL
A API botoi também fornece /v1/url-metadata, que faz o inverso: dado um URL, ele busca
a página e extrai suas tags Open Graph. Isso é útil para criar visualizações de links, cartões sociais
validadores ou ferramentas de auditoria de SEO.
curl -X POST https://api.botoi.com/v1/url-metadata \\
-H "Content-Type: application/json" \\
-d '{"url": "https://github.com/astro-community/astro-embed"}'
Resposta:
{
"success": true,
"data": {
"url": "https://github.com/astro-community/astro-embed",
"status": 200,
"title": "GitHub - astro-community/astro-embed",
"description": "Components to embed third-party media in Astro projects",
"og": {
"title": "astro-embed",
"description": "Components to embed third-party media in Astro projects",
"image": "https://opengraph.githubassets.com/...",
"type": "object",
"url": "https://github.com/astro-community/astro-embed",
"site_name": "GitHub"
}
}
}
Use isto para criar componentes de visualização de link em seu aplicativo:
async function getLinkPreview(url: string) {
const res = await fetch('https://api.botoi.com/v1/url-metadata', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url }),
});
const { data } = await res.json();
return {
title: data.og?.title ?? data.title,
description: data.og?.description ?? data.description,
image: data.og?.image,
siteName: data.og?.site_name,
};
}
Combine os dois endpoints: use /v1/url-metadata para verificar como suas páginas aparecem nas redes sociais
plataformas, e /v1/og/generate para criar as imagens que as fazem parecer boas.
Por que não executar o Satori você mesmo?
Você pode. Satori é de código aberto e produz resultados de qualidade. Mas executá-lo sozinho significa:
- Instalando e agrupando fontes personalizadas (Satori não usa fontes do sistema)
- Configurando um tempo de execução Node.js ou Edge Function para renderização de imagem
- Escrevendo modelos JSX para SVG e convertendo SVG para PNG com resvg
- Lidando com limites de memória em plataformas sem servidor ao renderizar imagens grandes
- Mantendo o pipeline conforme a API do Satori evolui
Uma chamada de API substitui tudo isso por uma única solicitação HTTP. Se suas necessidades de imagem OG são simples (título + descrição + marca), a abordagem da API economiza horas de configuração e manutenção contínua.
FAQ
- Qual é o tamanho das imagens OG geradas?
- Cada imagem tem 1200x630 pixels, o tamanho de imagem padrão do Open Graph recomendado pelo Facebook, Twitter/X, LinkedIn e Slack. A saída é um arquivo PNG.
- Preciso de uma chave de API?
- Não. O nível gratuito permite cinco solicitações por minuto sem chave de API. Para construir pipelines ou sites de alto tráfego que geram imagens em cada visualização de página, pegue uma chave na página de documentos da API do botoi para desbloquear limites de taxa mais altos.
- Posso personalizar fontes, cores ou layout?
- O parâmetro theme aceita "light" ou "dark" para controlar o esquema geral de cores. A API lida com a tipografia e o layout automaticamente com base no título e no comprimento da descrição. Para designs totalmente personalizados, gere sua imagem base com a API e pós-processe-a com sua própria lógica de sobreposição.
- Quão rápida é a geração da imagem?
- A API é executada em Cloudflare Workers na borda. A maioria das solicitações retorna um PNG finalizado em menos de 500 ms. Se você armazenar o resultado em cache (recomendado para sites estáticos), a geração ocorrerá apenas uma vez por combinação única de título, descrição e tema.
- O que o endpoint /v1/url-metadata faz?
- POST uma URL para /v1/url-metadata e a API busca essa página, analisa seu HTML e retorna metadados estruturados do Open Graph: og:title, og:description, og:image, og:type e tags de cartão do Twitter. Use-o para visualizar como qualquer URL aparece quando compartilhado nas redes sociais ou para extrair metadados para suas próprias visualizações de link.
Comece a construir com botoi
150+ endpoints de API para consultas, processamento de texto, geração de imagens e utilitários para desenvolvedores. Plano gratuito, sem cartão de crédito.