Fastify
FastifyFastify
Generate a unique OG image for every page, or any on-demand graphic, from a single Imejis template. The pattern below uses a Fastify route handler as a thin proxy: your API key stays on the server, and the browser (and social crawlers) only ever see your own URL.
Set two environment variables first: IMEJIS_API_KEY (from your dashboard) and IMEJIS_DESIGN_ID (any design's ID).
IMEJIS_API_KEY=your_api_key
IMEJIS_DESIGN_ID=your_design_id1 a handler that renders the image1. A handler that renders the image
This handler takes a title query param, POSTs it to Imejis as a component.property override, and sends the finished image back as a Buffer. Because the key is sent server-side, it never reaches the client.
import Fastify from "fastify"
const fastify = Fastify()
fastify.get("/og", async (request, reply) => {
const title = request.query.title ?? "Untitled"
const upstream = await fetch(
`https://render.imejis.io/v1/${process.env.IMEJIS_DESIGN_ID}`,
{
method: "POST",
headers: {
"dma-api-key": process.env.IMEJIS_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ "headline.text": title }),
}
)
const image = Buffer.from(await upstream.arrayBuffer())
reply.header("Content-Type", "image/jpeg")
// Renders are deterministic, so cache aggressively at the edge/CDN.
reply.header(
"Cache-Control",
"public, immutable, no-transform, max-age=31536000"
)
return reply.send(image)
})
await fastify.listen({ port: 3000 })2 point your metadata at it2. Point your metadata at it
Reference the handler from whatever renders your page's <head>, passing each page's real data. Social platforms fetch /og?title=… from your own domain, no key exposed.
<meta
property="og:image"
content="https://your-site.com/og?title=Hello%20from%20Fastify"
/>
<meta name="twitter:card" content="summary_large_image" />Override any field. Each dynamic component exposes keys like headline.text, title.color, or image.image. Send only the ones you want to change. A design's overridable fields are listed in its Share / API panel.