DEV Community

Cover image for Automate Instagram Carousel Posts with n8n + RenderPix
Özgür S.
Özgür S.

Posted on • Originally published at renderpix.dev

Automate Instagram Carousel Posts with n8n + RenderPix

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:

  1. Reads post data from Google Sheets (title, subtitle, date)
  2. Injects data into an HTML template
  3. Renders it as a 1080×1350px PNG using RenderPix
  4. Outputs images ready to upload to Buffer, Later, or any scheduling tool

Tools used:

  • n8n — workflow automation
  • RenderPix — HTML-to-image API
  • Google Sheets — data source

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

  1. Go to Credentials → Add Credential
  2. Search for RenderPix API
  3. Enter your API key (get a free key at renderpix.dev)
  4. 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>
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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:

  1. Build the HTML with your data
  2. Send it to RenderPix
  3. 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:

Top comments (0)