Why automate carousel creation
The standard workflow for Instagram carousels involves opening Figma or Canva, duplicating a template, swapping out text, exporting each slide, then uploading to a scheduling tool. For one post that's 10–15 minutes. For ten posts a week, it's a part-time job.
HTML-to-image rendering makes this automatable. You write an HTML template once, point it at a data source, and a workflow generates all the images in one run. Change the data, run again. The template stays the same.
What you need
- n8n — self-hosted or cloud (community nodes require self-hosted or a paid cloud plan)
- RenderPix account — free tier includes 100 renders/month
- Google Sheet — your post data source
Step 1: Install the RenderPix n8n node
Open your n8n instance and navigate to Settings → Community Nodes → Install. Enter n8n-nodes-renderpix and click Install. n8n will restart automatically.
Once restarted, add a new credential under Credentials → Add Credential → RenderPix API. Paste your API key from your RenderPix dashboard.
Step 2: Set up the data source
Create a Google Sheet with at least these columns:
| topic | title | subtitle |
|---|---|---|
| Productivity | 5 habits that changed my life | Start small. Stay consistent. |
| Design | Why white space matters | Less is always more. |
| Marketing | The hook formula | Attention → Interest → Action |
Each row becomes one carousel slide. Add as many rows as you need — the workflow processes all of them in a single run.
Step 3: Build the HTML template
The template is plain HTML and CSS. RenderPix renders it at 1080×1350px using a real Chromium instance, so any CSS that works in Chrome will work here.
<!DOCTYPE html>
<html><head><meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 1080px; height: 1350px;
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex; align-items: center; justify-content: center;
}
.card { width: 900px; text-align: center; color: white; }
.label { font-size: 18px; font-weight: 600; letter-spacing: 0.2em;
text-transform: uppercase; opacity: 0.7; margin-bottom: 24px; }
.title { font-size: 72px; font-weight: 800; line-height: 1.1; margin-bottom: 32px; }
.divider { width: 80px; height: 4px; background: rgba(255,255,255,0.5);
margin: 0 auto 32px; }
.subtitle { font-size: 28px; opacity: 0.85; line-height: 1.5; }
</style></head>
<body>
<div class="card">
<div class="label">${topic}</div>
<div class="title">${title}</div>
<div class="divider"></div>
<div class="subtitle">${subtitle}</div>
</div>
</body></html>
Step 4: Build the n8n workflow
Node 1 — Google Sheets
Add a Google Sheets node. Set Operation to Get Many, point it at your sheet, and enable Return All.
Node 2 — Code
Add a Code node to inject row data into the HTML template:
const items = [];
for (const item of $input.all()) {
const { topic, title, subtitle } = item.json;
const html = `<!DOCTYPE html><html><head><meta charset="UTF-8">
<style>/* your CSS here */</style></head>
<body>
<div class="card">
<div class="label">${topic}</div>
<div class="title">${title}</div>
<div class="divider"></div>
<div class="subtitle">${subtitle}</div>
</div>
</body></html>`;
items.push({ json: { html, topic, title } });
}
return items;
Node 3 — RenderPix
Add a RenderPix node and configure it: Operation → Render HTML, HTML → {{ $json.html }}, Width → 1080, Height → 1350, Format → PNG, Return as → Binary.
Node 4 — (Optional) Upload
Connect an S3 node, Google Drive node, or any storage destination to save the images. From there, connect a Buffer or Later node to schedule posting.
Performance
| Metric | Value |
|---|---|
| Render time per image | ~230ms |
| 10-post batch | ~3 seconds total |
| Output resolution | 1080×1350px (Instagram portrait) |
| Monthly renders — free tier | 100 |
| Monthly renders — Starter ($9/mo) | 2,000 |
What else you can build with the same pattern
Swap the HTML template and dimensions, and the same workflow generates:
- OG images for blog posts (1200×630px) — trigger on new post publish
- Certificates for course completions (1200×800px) — trigger from a form submission
- LinkedIn post cards (1200×627px) — trigger from a content calendar
- Email header images — trigger from a campaign scheduler
Workflow JSON available on GitHub. Import it directly into n8n: github.com/ozgurdogus/renderpixn8n
Replace Figma with a single fetch call
Full HTML and CSS support. Pre-warmed Chromium — no cold starts. Free tier included.
Also see: certificate generation tutorial and OG images with Next.js.