sodcalculator

10 Tech How-To

HTML to Image: Generate OG Images with CSS

Guide 10-19169 · Updated · Step by step

This guide shows you how to turn HTML and CSS into a static image, perfect for generating Open Graph (OG) images for social media links. You’ll write a normal HTML file, style it with CSS, and use a headless browser tool to capture it as a PNG. This approach gives you full design control—no graphic design software needed.

What You’ll Need

  • Node.js (version 14 or later) installed on your computer.
  • A text editor (like VS Code, Sublime Text, or Notepad).
  • Basic familiarity with HTML and CSS.
  • A terminal or command prompt.

Step-by-Step

  1. Create a project folder and navigate to it in your terminal. For example: mkdir og-image-generator && cd og-image-generator.
  2. Initialize a Node.js project by running npm init -y. This creates a package.json file.
  3. Install Puppeteer (a headless browser library) with npm install puppeteer. This will download a compatible version of Chromium.
  4. Create an HTML file named template.html. This will be your image template. Design it with CSS to the exact dimensions you want (e.g., 1200×630 pixels for most social platforms). Use inline styles or a <style> block.
  5. Create a JavaScript file named generate.js. This script will load your HTML, set the viewport size, and take a screenshot.
  6. Write the generation script. In generate.js, add the following code:
    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      
      // Set viewport to match your desired image size
      await page.setViewport({ width: 1200, height: 630 });
      
      // Load the HTML file
      await page.goto('file://' + __dirname + '/template.html', { waitUntil: 'networkidle0' });
      
      // Take a screenshot
      await page.screenshot({ path: 'og-image.png', type: 'png' });
      
      await browser.close();
      console.log('Image saved as og-image.png');
    })();
  7. Run the script with node generate.js. After a few seconds, you’ll see og-image.png in your folder.
  8. Use the image in your website’s <meta> tags, like <meta property="og:image" content="https://yourdomain.com/og-image.png">.

Common Mistakes

  • Forgetting to set the viewport – If you don’t set the viewport, Puppeteer defaults to 800×600, and your image will be cropped or scaled incorrectly.
  • Using external resources without waiting – If your HTML loads web fonts or images from a CDN, the screenshot may be taken before they load. Use waitUntil: 'networkidle0' to ensure everything is loaded.
  • Not using absolute paths for local files – When referencing local images or fonts in your HTML, use absolute paths (e.g., /Users/you/project/image.jpg) or ensure they are in the same directory and referenced correctly.
  • Ignoring device pixel ratio – For high-DPI displays, you may need to set deviceScaleFactor: 2 in the viewport to get a sharper image.

Tips

  • Use a CSS reset to avoid inconsistent margins/padding across browsers.
  • Design for the final size – Test your HTML at the exact image dimensions in a regular browser before running the script.
  • Use system fonts or self-hosted fonts to avoid external requests and speed up loading.
  • Add a fallback background color in case your main background image fails to load.
  • Automate the process by integrating the script into your build pipeline (e.g., a pre-commit hook or CI job).

Troubleshooting

  • Image is blank or white – Check if your HTML has a background color. If you’re using a gradient or image, ensure the path is correct and the file exists.
  • Text is cut off – The viewport is set to the image size, but your content might overflow. Use overflow: hidden on the body or a wrapper div, and test with a longer text to see if it clips.
  • Fonts not loading – If you’re using web fonts, ensure they are loaded before the screenshot. You can also use page.evaluate() to wait for document.fonts.ready.
  • Puppeteer fails to launch – This might be due to missing system dependencies. Run npx puppeteer browsers install or check the official Puppeteer troubleshooting guide.
  • Image looks blurry – Increase the deviceScaleFactor to 2 or 3 to capture a higher-resolution image.

Frequently Asked Questions

Can I use this method for dynamic content?

Yes, you can pass data to your HTML template using query parameters or by injecting variables into the page before taking the screenshot. For example, you can use page.setContent() with a template string.

What image size should I use for Open Graph?

The recommended size is 1200×630 pixels, but you can use any size that your platform supports. Check the specific platform’s documentation for exact requirements.

Can I generate multiple images at once?

Absolutely. Loop through an array of data and call the screenshot function for each one, saving with different filenames.

Is there a way to do this without Node.js?

Yes, you can use command-line tools like wkhtmltoimage or online services, but Puppeteer gives you more control and is free.

How do I add a custom font?

Include the font file in your project and reference it in your CSS using @font-face. Make sure the path is correct and the font is loaded before the screenshot.

Can I use CSS animations in the image?

No, screenshots capture a static moment. Animations will only appear at their initial state. If you need a specific frame, you can pause the animation before taking the screenshot.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →