Image OG dynamique

/api/og génère un SVG par requête, indexé par la chaîne de paramètres. En le référençant depuis <meta property="og:image">, chaque page peut émettre son propre aperçu sans avoir à livrer 100 variantes PNG. Le SVG est le chemin le plus léger ; les apps en production qui ont besoin d'une sortie raster font passer le SVG par resvg-js en aval.

Astuce
Les crawlers réseaux sociaux (Facebook, Twitter/X, LinkedIn) ne suivent pas les redirections sur og:image — l'URL doit répondre directement en 200. Les SVG sont rejetés par la plupart d'entre eux (ils attendent image/png ou image/jpeg) : utilisez le rasteriseur intégré de bext via /__bext/api/og pour une image PNG prête à l'emploi.

Aperçu en direct

aperçu OG généré

/api/og?title=Hello%2C%20OG&subtitle=rendered%20server-side&accent=d97706

src/app/api/og/route.tsTypeScript
// /api/og — emits a 1200x630 SVG you can use as <meta property="og:image">
export async function GET(req: Request) {
  const url = new URL(req.url);
  const title = url.searchParams.get("title") ?? "bext demos";
  const svg = '<svg ...><text>' + escapeXml(title) + '</text></svg>';
  return new Response(svg, {
    status: 200,
    headers: {
      "content-type": "image/svg+xml; charset=utf-8",
      "cache-control": "public, max-age=3600",  // query-string keys the cache
    },
  });
}

// Per-page metadata referencing the dynamic image.
export function generateMetadata({ searchParams }) {
  const title = searchParams.title ?? "bext";
  return {
    openGraph: {
      images: ["/api/og?title=" + encodeURIComponent(title)],
    },
  };
}