Custom Templates & Fonts
Using your own components and custom fonts for OG images
Custom OG Components
You can use any Takumi-compatible React component in place of StandardOgTemplate:
import { createOgResponse } from "@stdout-design/core/og";
function MyOGCard({ title, stat }: { title: string; stat: string }) {
return (
<div tw="flex flex-col w-full h-full items-center justify-center bg-slate-900 p-16">
<p tw="text-2xl text-slate-400 mb-4">{title}</p>
<p tw="text-8xl font-bold text-white">{stat}</p>
</div>
);
}
export async function GET() {
return createOgResponse(
<MyOGCard title="Monthly Active Users" stat="124.5K" />
);
}Custom Fonts
Font URLs work directly no fetch → arrayBuffer() conversion needed:
import { createOgResponse } from "@stdout-design/core/og";
import { StandardOgTemplate } from "@stdout-design/core/og";
export async function GET(data) {
return createOgResponse(
<StandardOgTemplate
title={data.title}
description={data.description}
siteName="My App"
/>,
{
fonts: [
"https://cdn.example.com/Inter-Bold.woff2",
{
name: "Inter",
data: "https://cdn.example.com/Inter-Regular.woff2",
weight: 400,
},
],
}
);
}Takumi accepts font URLs as bare strings or as descriptors it fetches and caches them on demand.
Locale Support
Pass locale directly to createOgResponse it auto-sets Takumi's lang option for proper text shaping and RTL handling:
import { createOgResponse } from "@stdout-design/core/og";
import { StandardOgTemplate } from "@stdout-design/core/og";
export async function GET(req: Request) {
const locale = new URL(req.url).searchParams.get("locale") ?? "en";
return createOgResponse(
<StandardOgTemplate
title={locale === "ar" ? "مرحبا بالعالم" : "Hello World"}
description="Localized OG image"
siteName="My App"
/>,
{ locale }
);
}For locale-aware OG images with font resolution and caching, use the full @stdout-design/core pipeline via compileTemplate + renderToPixels.
Other Frameworks (Hono, Express)
The same pattern works in any framework:
import { createOgResponse } from "@stdout-design/core/og";
import { StandardOgTemplate } from "@stdout-design/core/og";
import { Hono } from "hono";
const app = new Hono();
app.get("/og", (c) => {
return createOgResponse(
<StandardOgTemplate title={c.req.query("title") ?? "Default"} />,
);
});For locale-aware OG images with font resolution and caching, use the full core pipeline via compileTemplate + renderToPixels documented in the core package.
renderOgResponse: the studio-native pipeline
createOgResponse is the easiest way to get an OG image out of any React component. @stdout-design/core/og also exports renderOgResponse, a leaner alternative that renders through the same engine as studio dev/studio render, so output matches what you see in the studio pixel-for-pixel:
import { renderOgResponse } from "@stdout-design/core/og";
export async function GET() {
return renderOgResponse(
<MyOGCard title="Monthly Active Users" stat="124.5K" />,
{ width: 1200, height: 630, format: "webp", devicePixelRatio: 2 }
);
}| Option | Default | Description |
|---|---|---|
width | 1200 | Output width |
height | 630 | Output height |
format | "webp" | "webp", "png", or "jpeg" |
devicePixelRatio | 1 | Pixel density multiplier |
It's intentionally minimal no fonts, locale, or images options. Any failure returns a fallback error image instead of throwing, same as createOgResponse.
Reach for createOgResponse by default it covers fonts, locale, and images. Reach for renderOgResponse when you want OG output that matches the rest of your studio-rendered templates exactly, and you don't need those extra options. For full control (custom fonts, locale, remote images), use the core package API directly.