If you're creating Instagram carousels manually — designing each slide in Figma or Canva, exporting, uploading — you're wasting hours every week.
In this tutorial, I'll show you how to automate the entire process: take data from a spreadsheet, generate pixel-perfect carousel images, and have them ready to post in seconds.
No design tools. No manual work. Pure automation.
What We're Building
A workflow that:
- Reads post data from Google Sheets (title, subtitle, date)
- Injects data into an HTML template
- Renders it as a 1080×1350px PNG using RenderPix
- Outputs images ready to upload to Buffer, Later, or any scheduling tool
Tools used:
Why HTML Instead of Figma?
Most people reach for Figma or Canva when they need visuals. But for automation, HTML is far better:
- Fully dynamic — inject any data, any time
- Version controlled — store templates in Git
- No API limits — no per-template pricing
- Developer-friendly — CSS gives you full design control
- Fast — RenderPix renders in ~230ms with pre-warmed Chromium
Step 1: Install the RenderPix n8n Node
Open your n8n instance and go to:
Settings → Community Nodes → Install
Type n8n-nodes-renderpix and click Install.
n8n will restart automatically.
Step 2: Add Your RenderPix Credential
- Go to Credentials → Add Credential
- Search for RenderPix API
- Enter your API key (get a free key at renderpix.dev)
- Save
Step 3: Build the HTML Template
Here's a clean Instagram carousel slide template (1080×1350px):
<!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;
border-radius: 2px;
}
.subtitle {
font-size: 28px;
opacity: 0.85;
line-height: 1.5;
}
.footer {
position: absolute;
bottom: 60px;
left: 0;
right: 0;
text-align: center;
font-size: 18px;
opacity: 0.5;
letter-spacing: 0.1em;
}
</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>
<div class="footer">@youraccount</div>
</body>
</html>
The {{ title }}, {{ topic }}, and {{ subtitle }} placeholders will be replaced dynamically by n8n.
Step 4: Set Up Google Sheets
Create a sheet with 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 |
Step 5: Build the n8n Workflow
Node 1: Google Sheets (Read rows)
- Operation: Get Many
- Sheet: your spreadsheet
- Return All: ✅
Node 2: Code Node (Build HTML)
Add a Code node to inject data into the 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>
/* paste 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>
<div class="footer">@youraccount</div>
</body>
</html>
`;
items.push({ json: { html, topic, title } });
}
return items;
Node 3: RenderPix
- Operation: Render HTML
- HTML:
{{ $json.html }} - Width:
1080 - Height:
1350 - Format:
PNG - Return as:
Binary
Node 4: (Optional) Upload to S3 or Google Drive
Connect any storage node to save the images automatically.
Step 6: Run the Workflow
Click Execute workflow. For each row in your sheet, n8n will:
- Build the HTML with your data
- Send it to RenderPix
- Return a pixel-perfect 1080×1350px PNG
A sheet with 10 rows = 10 carousel images in ~3 seconds.
Results
Here's what you get:
- Speed: ~230ms per image
- Quality: Pixel-perfect, retina-ready
- Scale: 2,000 renders/month on Starter plan ($9)
- Flexibility: Change the template, re-run, done
Compare that to designing each slide manually in Figma — 10-15 minutes per post becomes 3 seconds total.
Taking It Further
Once you have this working, you can extend it:
- Connect to Airtable instead of Google Sheets
- Auto-upload to Buffer using the Buffer n8n node
- Add a webhook trigger to generate images on demand
- Use different templates for different content types
Conclusion
HTML-to-image rendering is one of the most underrated automation tricks. Once you have a template, generating 100 carousel posts takes the same time as generating 1.
If you try this workflow, drop a comment — I'd love to see what you build.
Links:
- Install node:
n8n-nodes-renderpix(Settings → Community Nodes) - GitHub: github.com/ozgurdogus/renderpixn8n
- Free API key: renderpix.dev
Top comments (0)