Hono
HonoHono
Generate a unique OG image for every page, or any on-demand graphic, from a single Imejis template. The pattern below uses a Hono route as a thin proxy: your API key stays on the server, and the browser (and social crawlers) only ever see your own URL. It runs anywhere Hono does, including edge runtimes.
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 route that renders the image1. A route that renders the image
This route takes a title query param, POSTs it to Imejis as a component.property override, and returns the finished image. Because the key is sent server-side, it never reaches the client.
import { Hono } from "hono"
const app = new Hono()
app.get("/og", async (c) => {
const title = c.req.query("title") ?? "Untitled"
const res = await fetch(
`https://render.imejis.io/v1/${process.env.IMEJIS_DESIGN_ID}`,
{
method: "POST",
headers: {
"dma-api-key": process.env.IMEJIS_API_KEY as string,
"Content-Type": "application/json",
},
body: JSON.stringify({ "headline.text": title }),
}
)
return c.body(res.body, 200, {
"Content-Type": "image/jpeg",
// Renders are deterministic, so cache aggressively at the edge/CDN.
"Cache-Control": "public, immutable, no-transform, max-age=31536000",
})
})
export default app2 point your metadata at it2. Point your metadata at it
Reference the route from your HTML <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%20world"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:image"
content="https://your-site.com/og?title=Hello%20world"
/>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.