Guide Mar 28, 2026

Convert HTML to Image API: Render Dynamic Cards and Templates in One Call

You have HTML. You need it as an image. One API call — no Chromium, no browser lifecycle, no infrastructure. Email previews, OG cards, certificates, notification images.

You have HTML. You need it as an image. You could spin up a headless browser, manage Chromium, scale infrastructure. Or you could make one API call.

Why HTML-to-Image?

The problem: Puppeteer + Chromium = infrastructure overhead. PageBolt removes that entirely.

JavaScript: One Function

async function htmlToImage(htmlString, options = {}) {
  const response = await fetch('https://pagebolt.dev/api/v1/screenshot', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.PAGEBOLT_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      html: htmlString,
      format: options.format || 'png',
      width: options.width || 1280,
      height: options.height || 720,
    }),
  });

  if (!response.ok) throw new Error(`API error: ${response.statusText}`);
  return response.arrayBuffer();
}

// Render an email template
const emailTemplate = `
  <div style="font-family: Arial; padding: 20px; background: #f5f5f5;">
    <h1>Order Confirmation</h1>
    <p>Your order #12345 has been confirmed.</p>
    <p><strong>Total:</strong> $99.99</p>
  </div>
`;

const imageBuffer = await htmlToImage(emailTemplate);
fs.writeFileSync('order-confirmation.png', Buffer.from(imageBuffer));

No browser management. No Chromium. One API call.

Python

import requests, os

def html_to_image(html_string, format='png', width=1280, height=720):
    response = requests.post(
        'https://pagebolt.dev/api/v1/screenshot',
        headers={
            'x-api-key': os.getenv('PAGEBOLT_API_KEY'),
            'Content-Type': 'application/json',
        },
        json={'html': html_string, 'format': format, 'width': width, 'height': height}
    )
    if response.status_code != 200:
        raise Exception(f"API error: {response.status_code}")
    return response.content

# Certificate template
certificate_html = """
<div style="width:800px;height:600px;border:3px solid gold;padding:40px;
  text-align:center;font-family:serif;background:linear-gradient(to bottom,#fff9e6,#fffdf0)">
  <h1>Certificate of Completion</h1>
  <p style="font-size:18px;margin-top:40px">This certifies that</p>
  <h2>Jane Doe</h2>
  <p>Has successfully completed Advanced Python Programming</p>
  <p style="margin-top:40px">March 28, 2026 — Verified ✓</p>
</div>
"""

with open('certificate.png', 'wb') as f:
    f.write(html_to_image(certificate_html))

Real-World: Dynamic Email Preview Cards

Render email templates before sending to catch layout issues:

async function previewEmailTemplate(templateHtml, recipientName) {
  const personalized = templateHtml.replace('{{name}}', recipientName);
  return htmlToImage(personalized, { width: 600, height: 800 });
}

const template = `
  <div style="font-family:'Helvetica Neue',sans-serif;max-width:600px">
    <h2>Hello {{name}},</h2>
    <p>Your order is on the way.</p>
  </div>
`;

const preview = await previewEmailTemplate(template, 'Alice');
// Send to QA team for review before email blast

Batch: 100 Personalized Images in Parallel

const certificates = Array.from({ length: 100 }, (_, i) => `
  <div style="text-align:center;padding:40px;border:2px solid gold">
    <h1>Certificate #${i + 1}</h1>
    <p>Awarded to User ${i + 1}</p>
  </div>
`);

const images = await Promise.all(certificates.map(html => htmlToImage(html)));
// All 100 rendered in parallel — ~800ms total

Cost: 100 images = 100 API requests ≈ $5–10/month on the Growth plan. Self-hosted Chromium = $200–500/month infrastructure + developer time.

Supported Rendering Features

FeatureSupported
CSS: Flexbox, Grid, Gradients, Shadows
Google Fonts, @font-face
JavaScript execution (final frame)
Inline base64 images
SVG (inline or external)
Custom dimensions (any width/height)
Formats: PNG, JPEG, WebP
Transparent background (PNG)

Limitations

Getting Started

  1. Sign upFree tier: 100 requests/month, no credit card
  2. Set your API keyPAGEBOLT_API_KEY=your_key
  3. Copy the JS or Python example above — it works as-is
  4. Render your first template — HTML → PNG in one call

No infrastructure. No browser management. Just HTML → Image.

Convert HTML to image — free

100 requests/month, no credit card. Email previews, OG cards, certificates — any HTML string to PNG in one API call.

Get API key free →