Spring Boot
Spring bootSpring Boot
Generate a unique OG image for every page, or any on-demand graphic, from a single Imejis template. The pattern below uses a Spring @RestController 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 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 with the dma-api-key header, and returns the finished image bytes. Because the key is sent server-side, it never reaches the client.
package com.example.og;
import java.util.Map;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestClient;
@RestController
public class OgController {
private final RestClient client = RestClient.create();
@GetMapping("/og")
public ResponseEntity<byte[]> og(
@RequestParam(defaultValue = "Untitled") String title) {
String designId = System.getenv("IMEJIS_DESIGN_ID");
String apiKey = System.getenv("IMEJIS_API_KEY");
byte[] image = client.post()
.uri("https://render.imejis.io/v1/" + designId)
.header("dma-api-key", apiKey)
.contentType(MediaType.APPLICATION_JSON)
.body(Map.of("headline.text", title))
.retrieve()
.body(byte[].class);
return ResponseEntity.ok()
.contentType(MediaType.IMAGE_JPEG)
// Renders are deterministic, so cache aggressively at the edge/CDN.
.header("Cache-Control",
"public, immutable, no-transform, max-age=31536000")
.body(image);
}
}2 point your template at it2. Point your template at it
Reference the controller from your view or meta tags, passing each page's real data. Social platforms fetch /og?title=… from your own domain, no key exposed.
<meta
property="og:image"
th:attr="content=|https://your-site.com/og?title=${#uris.escapeQueryParam(post.title)}|"
/>
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:image"
th:attr="content=|https://your-site.com/og?title=${#uris.escapeQueryParam(post.title)}|"
/>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.