Most developers generate images like this:
const html = `
<div style="...">
<h1>${post.title}</h1>
<p>${post.author} · ${post.date}</p>
</div>
`;
Enter fullscreen mode Exit fullscreen mode
This works — until it doesn’t.
- Special characters break the HTML (
&,<,>in titles) - The template grows and the string becomes harder to maintain
- Reusing the same template across environments gets messy
- No clear separation between design and data
A cleaner approach: template variables
Instead of interpolating values into HTML strings, pass them separately:
const response = await fetch('https://renderpix.dev/v1/render', {
method: 'POST',
headers: {
'X-API-Key': 'rpx_your_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
html: `
<div style="width:1200px;height:630px;background:#0f172a;
display:flex;flex-direction:column;justify-content:center;
padding:80px;font-family:sans-serif">
<div style="color:#22d3ee;font-size:18px">{{domain}}</div>
<div style="color:white;font-size:52px;font-weight:bold;line-height:1.2">
{{title}}
</div>
<div style="color:#94a3b8;font-size:20px;margin-top:24px">
{{author}} · {{date}}
</div>
</div>
`,
vars: {
title: post.title,
author: post.author,
date: post.publishedAt,
domain: 'myblog.com'
},
width: 1200,
height: 630,
format: 'png'
})
});
Enter fullscreen mode Exit fullscreen mode
The HTML template stays clean. Values are injected at render time — no string interpolation, no escaping issues.
How it works
RenderPix does a find-and-replace before rendering the page:
-
{{title}}→ value ofvars.title -
{{author}}→ value ofvars.author - Missing key? The placeholder stays as-is — no errors thrown.
This means you can store your HTML template as a file, an environment variable, or a database field, and just swap the vars object per request.
The real power: combine with batch rendering
Template variables get interesting when you need multiple images at once.
One HTML template + N different vars objects = N unique images, one API request:
const OG_TEMPLATE = `
<div style="width:1200px;height:630px;background:#0f172a;
display:flex;flex-direction:column;justify-content:center;padding:80px">
<div style="color:#22d3ee;font-size:18px;margin-bottom:16px">{{domain}}</div>
<div style="color:white;font-size:52px;font-weight:bold;line-height:1.2">{{title}}</div>
<div style="color:#94a3b8;font-size:20px;margin-top:24px">{{author}} · {{date}}</div>
</div>
`;
const response = await fetch('https://renderpix.dev/v1/batch', {
method: 'POST',
headers: {
'X-API-Key': 'rpx_your_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
items: blogPosts.map(post => ({
html: OG_TEMPLATE,
vars: {
title: post.title,
author: post.author,
date: post.date,
domain: 'myblog.com'
},
width: 1200,
height: 630,
format: 'png'
}))
})
});
const { results } = await response.json();
// results[0].url, results[1].url, ...
// 50 unique OG images. One request.
Enter fullscreen mode Exit fullscreen mode
Without template variables, this would be 50 different HTML strings to maintain. With them, it’s one.
Use cases
This pattern works well anywhere you have a fixed design and variable data:
- OG images — one template per blog, dynamic per post
- Certificates — one template per course, dynamic per student
- Invoices — one template per company, dynamic per transaction
- Social cards — one brand template, different content daily
Available on all plans
Template variables work on free, starter, pro, and scale — no upgrade needed to try it.
If you want to test it: renderpix.dev gives you 100 free renders/month, no credit card required.
답글 남기기