Générez des images Open Graph avec un seul appel API, aucun Next.js requis
Utilisez l'API d'image botoi OG pour générer des cartes sociales PNG 1 200 x 630 à partir de n'importe quel framework. Fonctionne avec les plateformes Astro, Django, Rails, Laravel et CMS sans tête.
Votre article de blog est partagé sur Twitter. Au lieu d'un aperçu riche avec une carte de titre, le lien affiche un boîte grise vierge. Ou pire, un favicon étiré. Chaque partage sans image OG appropriée est un clic manqué.
La solution populaire est celle de Vercel @vercel/og bibliothèque. Ça marche bien, mais c'est verrouillé
Next.js et l'infrastructure de Vercel. Satori (le moteur derrière lui) a besoin d'un runtime Node.js avec des
capacités de chargement de polices. Si vous construisez avec Astro, Django, Rails, Laravel, Hugo ou tout autre
cadre, vous êtes seul.
Il existe une approche plus simple : envoyez une requête POST à une API et récupérez un PNG 1 200 x 630 terminé. Aucune dépendance Node.js. Pas de verrouillage du cadre. Aucun pipeline de rendu d’image à maintenir.
Une requête POST, un retour PNG
La botoi ET API d'image accepte un corps JSON avec votre titre, votre description et votre préférence de thème. Il renvoie des données binaires PNG brutes.
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
C'est ça. La réponse est un fichier PNG que vous pouvez enregistrer, servir ou télécharger sur un CDN :
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 48271
(binary PNG data, 1200x630px)
L'API gère la typographie, la mise en page et le dimensionnement approprié. Vous transmettez du texte, vous obtenez une image.
Intégration Astro : générer des images OG au moment de la construction
La génération de sites statiques d'Astro rend cela particulièrement propre. Créez une route API dynamique qui récupère
Images OG pendant la construction et les sert de statique .png fichiers.
// 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',
},
});
};
Pendant astro build, cette route génère un PNG pour chaque publication. Les fichiers de sortie atterrissent dans
votre dist/og/ répertoire en tant qu’actifs statiques. Pas de génération d'images d'exécution, pas de serveur sans serveur
fonction, pas de démarrage à froid.
Référencez les images dans l'en-tête de votre page :
<!-- 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\`} />
Chaque page reçoit une carte sociale unique, générée une fois lors de la construction et mise en cache pour toujours par les CDN.
Intégration Django et Rails
Les frameworks rendus par le serveur peuvent générer des images OG à la demande et mettre le résultat en cache.
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'),
]
La @cache_page le décorateur stocke l’image générée pendant 24 heures. Après le premier
demande, Django sert directement le PNG mis en cache sans avoir à nouveau recours à l'API.
Rails
# 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'
Les deux exemples suivent le même schéma : recherchez le message par slug, POSTez le titre et la description. à l'API et renvoie le PNG avec les en-têtes de mise en cache. Le framework gère la mise en cache ; l'API gère génération d'images.
Intégration CMS Headless : générer lors de la publication
Si votre contenu réside dans un CMS sans tête comme Strapi, Contentful ou Sanity, vous pouvez générer OG images chaque fois qu’un éditeur publie ou met à jour un article. Connectez un webhook qui se déclenche sur le contenu changements.
Gestionnaire de webhook générique
// 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}\`);
}
Crochet de cycle de vie 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' },
});
},
};
Cette approche est utile pour les équipes où les éditeurs de contenu publient via un CMS et où les développeurs ne le font pas. souhaitez exécuter un pipeline de construction pour chaque modification de texte. L'image OG se régénère automatiquement lorsque le modifier le titre ou la description du message.
Bonus : extrayez les métadonnées OG de n'importe quelle URL
L'API botoi fournit également /v1/url-metadata, ce qui fait l'inverse : étant donné une URL, il récupère
la page et extrait ses balises Open Graph. Ceci est utile pour créer des aperçus de liens, des cartes sociales
validateurs ou outils d’audit 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"}'
Réponse:
{
"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"
}
}
}
Utilisez-le pour créer des composants d'aperçu de lien dans votre application :
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,
};
}
Combinez les deux points de terminaison : utilisez /v1/url-metadata pour vérifier comment vos pages apparaissent sur les réseaux sociaux
plates-formes, et /v1/og/generate pour créer les images qui leur donnent une belle apparence.
Pourquoi ne pas diriger Satori vous-même ?
Tu peux. Satori est open source et produit un résultat de qualité. Mais l’exécuter vous-même signifie :
- Installation et regroupement de polices personnalisées (Satori n'utilise pas de polices système)
- Configuration d'un runtime Node.js ou d'une fonction Edge pour le rendu d'image
- Écriture de modèles JSX vers SVG et conversion de SVG en PNG avec resvg
- Gestion des limites de mémoire sur les plates-formes sans serveur lors du rendu d'images volumineuses
- Maintenir le pipeline à mesure que l'API de Satori évolue
Un appel API remplace tout cela par une seule requête HTTP. Si vos besoins en matière d'image OG sont simple (titre + description + branding), l'approche API permet d'économiser des heures de configuration et entretien continu.
FAQ
- Quelle est la taille des images OG générées ?
- Chaque image mesure 1 200 x 630 pixels, la taille d'image Open Graph standard recommandée par Facebook, Twitter/X, LinkedIn et Slack. La sortie est un fichier PNG.
- Ai-je besoin d’une clé API ?
- Non. L’offre gratuite autorise 5 requêtes par minute sans clé API. Pour créer des pipelines ou des sites à fort trafic qui génèrent des images sur chaque page vue, récupérez une clé sur la page de documentation de l'API botoi pour débloquer des limites de débit plus élevées.
- Puis-je personnaliser les polices, les couleurs ou la mise en page ?
- Le paramètre de thème accepte « clair » ou « sombre » pour contrôler la palette de couleurs globale. L'API gère automatiquement la typographie et la mise en page en fonction de la longueur de votre titre et de votre description. Pour des conceptions entièrement personnalisées, générez votre image de base avec l'API et post-traitez-la avec votre propre logique de superposition.
- Quelle est la vitesse de génération des images ?
- L'API s'exécute sur Cloudflare Workers en périphérie. La plupart des requêtes renvoient un fichier PNG terminé en moins de 500 ms. Si vous mettez le résultat en cache (recommandé pour les sites statiques), la génération n'a lieu qu'une seule fois par combinaison unique de titre, de description et de thème.
- Que fait le point de terminaison /v1/url-metadata ?
- POSTez une URL vers /v1/url-metadata et l'API récupère cette page, analyse son code HTML et renvoie les métadonnées Open Graph structurées : og:title, og:description, og:image, og:type et les balises Twitter Card. Utilisez-le pour prévisualiser la façon dont une URL apparaît lorsqu'elle est partagée sur les réseaux sociaux, ou pour extraire des métadonnées dans vos propres aperçus de liens.
Commencez a construire avec botoi
150+ endpoints API pour la recherche, le traitement de texte, la generation d'images et les utilitaires pour developpeurs. Offre gratuite, sans carte bancaire.