Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To convert HTML to JPG, render the HTML in a browser engine and capture the rendered page as a JPEG. For a single file, open it in a current browser and export a screenshot. For repeatable work, automate Chromium with Puppeteer or Playwright, wait for fonts, images, and JavaScript to finish, then save with JPEG settings. The correct method depends on whether your input is a live URL, a local HTML file, or an HTML string.

Choose the conversion method

Need Best fit Reason
One occasional image Browser capture Almost no setup and easy visual control.
JavaScript automation using Chrome or Firefox Puppeteer A JavaScript browser-automation API with page screenshot support.
Cross-browser automation and explicit image controls Playwright JPEG type, quality, scale, path, element, and full-page options.
PHP application integration Browsershot URL, arbitrary HTML, and local-file inputs through Puppeteer and headless Chrome.
Production API or AI-agent workflow ScreenshotNeo Clean shots, only clean shots billed, and a $5 paid plan for 3,000 shots.

Convert HTML to JPG in a browser

This is the fastest approach for an occasional conversion.

  1. Open the live URL or the local .html file in a current browser.
  2. Wait until the page has finished loading. Check that web fonts, images, charts, and data are visible.
  3. Use the browser’s screenshot, capture, or print/export feature. Select the full page if the document extends below the viewport.
  4. Choose JPEG/JPG as the output format when the capture tool offers it. If it only exports PNG, convert that PNG to JPG with an image editor or an image-conversion utility.
  5. Open the resulting JPG and inspect small text, transparency, and the bottom of the page before sharing it.

Manual capture is not reproducible: browser zoom, viewport size, loaded fonts, and timing can change the result. Use automation when the conversion runs repeatedly or must produce identical dimensions.

Convert a URL or HTML file with Puppeteer

Puppeteer automates a browser and exposes page screenshots. Install it in a Node.js project:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install puppeteer

Save this as html-to-jpg.mjs:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({
  path: 'page.jpg',
  type: 'jpeg',
  quality: 90,
  fullPage: true
});
await browser.close();

Run it with node html-to-jpg.mjs. Replace the URL with your page. For a local file, use an absolute file URL:

import { pathToFileURL } from 'node:url';
const fileUrl = pathToFileURL('/absolute/path/to/index.html').href;
await page.goto(fileUrl, { waitUntil: 'networkidle2' });

For generated markup, set the page content instead of navigating:

await page.setContent('<!doctype html><html><body><h1>Report</h1></body></html>', {
  waitUntil: 'networkidle0'
});

Confirm the exact screenshot options supported by the Puppeteer version installed in your project. A page can report network idle before an application has finished rendering; in that case wait for a known selector, a short delay, or the application’s own ready signal.

Convert HTML to JPG with Playwright

Playwright’s screenshot API accepts type: 'jpeg' and exposes quality, scale, path, and fullPage. Install the package and browser:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
npm install playwright
npx playwright install chromium
import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
  path: 'page.jpg',
  type: 'jpeg',
  quality: 90,
  fullPage: true,
  scale: 'css'
});
await browser.close();

scale: 'css' keeps dimensions tied to CSS pixels. Use device-scale capture when you deliberately need a higher-resolution raster. To capture one component rather than the whole document:

await page.locator('.invoice').screenshot({
  path: 'invoice.jpg', type: 'jpeg', quality: 92
});

Playwright can also target Firefox or WebKit by replacing chromium with the desired browser engine. Pin package and browser versions when pixel-level reproducibility matters.

Handle local files, HTML strings, and PHP

Local HTML files

Use a file:// URL with Puppeteer or Playwright, preferably as an absolute path. Relative CSS, image, and font URLs must resolve from that file’s directory. If your page relies on module imports or server routes, serve the directory over a local HTTP server instead; browser security rules can restrict local-file requests.

Arbitrary HTML strings

Use Puppeteer’s page.setContent() or Playwright’s page.setContent(). Include the complete document, CSS, and any data needed to render. External resources still need network access and time to load.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PHP with Browsershot

Spatie Browsershot wraps Puppeteer and headless Chrome. Typical inputs are a URL, an HTML string, or a local file:

use SpatieBrowsershotBrowsershot;

Browsershot::url('https://example.com')
    ->save('/absolute/path/page.jpg');

Browsershot::html('<h1>Invoice</h1>')
    ->save('/absolute/path/invoice.jpg');

Browsershot::htmlFromFilePath('/absolute/path/index.html')
    ->save('/absolute/path/local.jpg');

Configure the Node.js, npm, and Chrome paths required by your server deployment. The exact Browsershot and Puppeteer options depend on the versions in your application.

Control the rendered result

Viewport and page length

Set a fixed viewport width and height. Use fullPage: true when content continues below the initial viewport; otherwise only the visible area becomes the JPG. Full-page capture creates a potentially very tall image, so consider capturing a specific element or splitting long documents.

Fonts, images, and asynchronous data

Wait for web fonts with document.fonts.ready, wait for a meaningful selector, and ensure lazy images have entered the viewport. A network-idle event is useful but not a guarantee that application data is complete. If you control the page, expose a ready marker such as window.renderComplete = true and wait for it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JPEG quality, scale, and transparency

JPEG is lossy. Quality around 85–95 is a practical starting range for text-heavy pages; inspect the output rather than assuming a setting is ideal. JPEG has no transparency, so transparent backgrounds are flattened against the browser’s capture background. Use PNG when lossless text edges or transparency are required, then convert only when a JPG deliverable is mandatory.

Stable output

  • Pin browser and automation-package versions.
  • Use the same viewport, device scale, timezone, locale, and fonts on every worker.
  • Disable animations or wait for them to finish.
  • Mock changing timestamps, ads, and randomized content in visual tests.

Troubleshoot common conversion failures

Symptom Likely cause Fix
Only the top portion appears Viewport screenshot was requested. Set fullPage: true, or capture the required element.
Fonts or images are missing Capture occurred before asynchronous resources loaded. Wait for a selector, document.fonts.ready, image completion, or application-ready state.
Output is blurry or unexpectedly huge Device scale and CSS scale were mixed. Choose a deliberate viewport and scale; use CSS scale for predictable dimensions.
Different machines produce different JPGs Browser, fonts, viewport, or page data differ. Pin versions, install identical fonts, fix dimensions, and control dynamic content.
Local CSS or images do not load Relative paths or file-origin restrictions. Use absolute paths, a correct file:// URL, or serve the directory locally.
Blank page or timeout Blocked navigation, bot protection, a JavaScript error, or an unready app. Check the URL manually, inspect browser console/network errors, increase the navigation timeout, and wait for the page’s real ready condition.
Text has JPEG halos Lossy compression. Increase quality or use PNG when the receiving system permits it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request renders a URL and returns PNG, JPEG, WebP, or PDF. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report X-Page-Verdict and X-Billed.

It supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper and margin controls, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for selectors/delays/network idle, blocking ads/trackers/requests/resource types, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, user-selected cache TTL, signed public-image links, asynchronous jobs with signed webhooks, up to 100 URLs per bulk call, a usage API, an OpenAPI specification, and parameter names compatible with many other screenshot APIs. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the ScreenshotNeo API documentation for authentication and options.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; all features are available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to start.

Cost, performance, and reliability decisions

Local Puppeteer or Playwright avoids per-image API charges but requires browser binaries, memory, process supervision, security updates, and your own handling of retries and blocked pages. Reuse a browser process for batches instead of launching one browser per URL, while creating a fresh page or context for isolation. Limit concurrency so CPU and memory pressure do not cause timeouts.

An API removes browser deployment work and can report whether a result was a clean, billable capture. Caching can reduce repeated rendering; choose a TTL that matches how often the source changes. For high-volume jobs, asynchronous capture and signed webhooks prevent long-running HTTP requests, while bulk capture can submit up to 100 URLs per call.

Frequently asked questions

Frequently Asked Questions

Can I convert HTML to JPG without installing software?

Yes. Open the HTML in a current browser and use its capture or screenshot feature. Automation is preferable when you need repeatable output.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is JPG the same as JPEG?

Yes. JPG and JPEG refer to the same lossy image format; the three-letter extension is a legacy filename convention.

Why does a local HTML file look different from its hosted version?

Local files may resolve relative assets differently and can be restricted by browser security rules. Test with an absolute file URL or serve the directory through a local HTTP server.

Should I use PNG instead of JPG for text?

Use PNG when lossless edges or transparency matter. Choose JPG when a smaller, widely supported lossy image is required.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.