NestJS icon

NestJS

NestjsNestJS

Generate a unique OG image for every page, or any on-demand graphic, from a single Imejis template. The pattern below uses a NestJS controller 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).

.env
IMEJIS_API_KEY=your_api_key
IMEJIS_DESIGN_ID=your_design_id

1 a controller that renders the image1. A controller that renders the image

This controller takes a title query param, POSTs it to Imejis as a component.property override, and streams the finished image back through the Response. Because the key is sent server-side, it never reaches the client.

og.controller.ts
import { Controller, Get, Query, Res } from "@nestjs/common"
import { Response } from "express"
 
@Controller()
export class OgController {
  @Get("og")
  async og(@Query("title") title = "Untitled", @Res() res: Response) {
    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 as string,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ "headline.text": title }),
      }
    )
 
    const image = Buffer.from(await upstream.arrayBuffer())
 
    res.set({
      "Content-Type": "image/jpeg",
      // Renders are deterministic, so cache aggressively at the edge/CDN.
      "Cache-Control": "public, immutable, no-transform, max-age=31536000",
    })
    res.send(image)
  }
}

2 point your metadata at it2. Point your metadata at it

Reference the controller 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.

head.html
<meta
  property="og:image"
  content="https://your-site.com/og?title=Hello%20from%20NestJS"
/>
<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.