Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesTo capture a form when it is submitted, intercept the form’s submit event, call event.preventDefault(), render the element you want with html2canvas, and export the returned canvas as an image. For dependable receipts, submit the values into a separate, ordinary-text preview element and capture that preview rather than relying on every browser’s rendering of live controls.
Capture a form on submit
html2canvas runs in the browser. It accepts a DOM element and returns a Promise that resolves to a canvas. The submission handler therefore has three asynchronous-safe stages: stop the normal navigation, ensure the capture target contains the submitted state, and export or display the canvas.
Minimal working example
import html2canvas from 'html2canvas';
const form = document.querySelector('#my-form');
const preview = document.querySelector('#form-preview');
form.addEventListener('submit', async (event) => {
event.preventDefault();
try {
const canvas = await html2canvas(preview);
const link = document.createElement('a');
link.download = 'form.png';
link.href = canvas.toDataURL('image/png');
link.click();
} catch (error) {
console.error('Could not capture the form:', error);
}
});
Install the package with your normal JavaScript package manager (for example, npm install html2canvas) and bundle the module. The selector passed to html2canvas can be the form itself, a confirmation panel, or any containing element.
Complete page example
<form id="my-form">
<label>Name <input name="name" required></label>
<label>Email <input name="email" type="email" required></label>
<label>Plan
<select name="plan">
<option>Starter</option>
<option>Growth</option>
</select>
</label>
<label><input name="updates" type="checkbox"> Send updates</label>
<button type="submit">Submit and save</button>
</form>
<section id="form-preview" hidden>
<h2>Submission receipt</h2>
<p>Name: <span data-value="name"></span></p>
<p>Email: <span data-value="email"></span></p>
<p>Plan: <span data-value="plan"></span></p>
<p>Updates: <span data-value="updates"></span></p>
</section>
<output id="image-output"></output>
<script type="module">
import html2canvas from 'html2canvas';
const form = document.querySelector('#my-form');
const preview = document.querySelector('#form-preview');
const output = document.querySelector('#image-output');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const data = new FormData(form);
preview.querySelector('[data-value="name"]').textContent = data.get('name') || '';
preview.querySelector('[data-value="email"]').textContent = data.get('email') || '';
preview.querySelector('[data-value="plan"]').textContent = data.get('plan') || '';
preview.querySelector('[data-value="updates"]').textContent = data.has('updates') ? 'Yes' : 'No';
preview.hidden = false;
try {
const canvas = await html2canvas(preview, {
backgroundColor: '#ffffff',
scale: window.devicePixelRatio || 1
});
output.replaceChildren(canvas);
const download = document.createElement('a');
download.download = 'form-receipt.png';
download.href = canvas.toDataURL('image/png');
download.textContent = 'Download PNG';
output.append(download);
} catch (error) {
console.error('Could not capture the form:', error);
output.textContent = 'The receipt could not be rendered.';
}
});
</script>
The preview is made visible before capture because an element with display:none has no useful layout to render. You can place it off-screen instead if it must not appear in the interface, but it still needs measurable dimensions. After capture, hide it again if appropriate.
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
Live form versus a receipt preview
Capturing the live form
Passing html2canvas(form) is the shortest approach. It works when a visual snapshot of the current DOM is enough and you have tested the controls and browsers you support.
Do not assume that a changed input value is always reproduced. An individual report against version 1.4.1 described a stale input value in Firefox 124.0.2 and iOS 17 Safari. That report does not establish that every input or browser fails, but it is a reason to verify your exact fields.
Capturing a dedicated preview
For an invoice, confirmation, audit record, or other image whose text must be correct, read the submitted FormData and write the values into normal text nodes in a receipt element. This makes labels, checkbox states, selected options, and formatting explicit instead of depending on how a live form control is reconstructed.
Use textContent, not innerHTML, for user-entered values. It prevents submitted text from becoming markup in the preview. Format dates, currency, and redacted fields before assigning them to the receipt.
Recommended Free Tools
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Exporting and displaying the result
PNG, JPEG, and WebP
PNG is the safest default for text and transparent areas:
const png = canvas.toDataURL('image/png');
const jpeg = canvas.toDataURL('image/jpeg', 0. nueve);
const webp = canvas.toDataURL('image/webp', 0.9);
Replace the accidental-looking decimal in production with 0.9; the valid JPEG example is:
const jpeg = canvas.toDataURL('image/jpeg', 0.9);
JPEG discards transparency and introduces compression artifacts around text. WebP support depends on the browser and your downstream workflow. To show the result, assign the canvas directly or use a data URL in an image:
document.querySelector('#image-output').replaceChildren(canvas);
const image = new Image();
image.alt = 'Form receipt';
image.src = canvas.toDataURL('image/png');
Download without leaving the page
Create an anchor, set its download filename and data URL, and click it from the submit handler. Some browsers apply download restrictions to synthetic clicks; if that happens, display a normal download link for the user to click.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Important html2canvas limits
It reconstructs the DOM, not the browser’s pixels
html2canvas traverses the DOM and builds a canvas from information available to JavaScript. The project documentation says: “The screenshot is based on the DOM and as such may not be 100% accurate to the real representation but builds the screenshot based on the information available on the page.” Expect differences from a native operating-system screenshot, especially for unsupported CSS, fonts, filters, and browser-specific rendering.
Cross-origin images
An image hosted on another origin must be served with suitable CORS headers, or loaded through a carefully controlled same-origin proxy. Setting useCORS: true requests CORS-enabled loading; it cannot override browser content policy:
const canvas = await html2canvas(target, {
useCORS: true,
backgroundColor: '#fff'
});
If the image server does not grant access, use a same-origin asset, configure the server correctly, or omit the image from the capture. Avoid arbitrary third-party proxy services for private form data.
CSS and browser support
CSS coverage is selective, and html2canvas relies on browser APIs such as window and document. Test the actual page on every supported browser and device. Simplify the capture view when a critical style is missing, and provide a text or PDF alternative when an image is not essential.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Dimensions and long content
Canvas limits vary by browser, device memory, and graphics implementation. Very tall receipts can be clipped, blank, or fail during export. For a clipped element, try dimensions based on its scroll area:
const canvas = await html2canvas(target, {
windowWidth: target.scrollWidth,
windowHeight: target.scrollHeight
});
This is not a universal maximum or guarantee. Split long receipts into pages, reduce the scale, or capture smaller sections when necessary. The library also supports options for scaling, cropping, and excluding marked elements; consult the version’s API documentation and test each option in your target browsers.
Server-side rendering
Do not call html2canvas during Node.js server rendering. It needs browser objects and a laid-out document. Run the capture after the page has loaded in a real browser, or use a server-side screenshot service.
Reliable submission workflow
- Validate first. Let native constraint validation run, or validate your data before starting capture. A submit listener normally runs only after required fields pass browser validation.
- Prevent navigation. Call
event.preventDefault()when the page must stay in place while the Promise resolves. If the form must also be sent to a server, submit it withfetchafter creating the receipt or run both operations with explicit error handling. - Freeze the state. Read
FormDataimmediately, disable duplicate submission if needed, and populate the preview with text nodes. - Wait for assets. Ensure fonts and images needed by the receipt have loaded. For images, use same-origin files or CORS-enabled responses.
- Capture one target. Pass the receipt element rather than the entire document to reduce work and avoid unrelated overlays.
- Handle failure visibly. Keep the form data available, log the error for diagnostics, and offer a retry or a text confirmation.
- Release UI state. Re-enable the submit button in a
finallyblock and remove temporary preview content when it is no longer needed.
Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The image contains an old input value | The live control’s value was not reflected in the reconstructed canvas. | Verify the target’s current state; for a dependable receipt, copy FormData into a dedicated preview and capture that. |
| Images are missing or export throws a security error | Cross-origin content lacks permission. | Use same-origin assets, configure CORS on the image host, and set useCORS: true only when that cooperation exists. |
| Styles or fonts look different | The CSS feature is not fully supported by the library or the asset was not loaded. | Simplify the capture stylesheet, wait for fonts, and test the exact browser/device combination. |
| A long receipt is clipped or blank | A browser canvas dimension or memory limit was reached. | Capture a smaller element, reduce scale, use scroll dimensions, or split the receipt. |
| Nothing renders in Node.js | No browser window or document exists. |
Run html2canvas in the browser, or use a browser-based screenshot API. |
| The normal form navigation still occurs | The handler is attached to the wrong form or preventDefault() was omitted. |
Attach to the form’s submit event and call event.preventDefault() before awaiting capture. |
Or skip the browser setup
If you need a URL screenshot rather than a browser-side form receipt, ScreenshotNeo provides a single HTTP call. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing result in X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Free tools Windows power users keep installed
One-click scans. No signup required.
See the ScreenshotNeo website and API documentation for authentication and options. A basic call is:
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The equivalent Python and Node.js requests are:
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector elements, dark mode, device presets and custom viewports, retina scale, PDF settings, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and familiar parameter names for easier migration. Every feature is on every plan. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free to start with those 1,000 monthly screenshots.
Choosing the right approach
| Need | Best fit |
|---|---|
| A receipt must show submitted values accurately | Build a dedicated preview from FormData, then capture it with html2canvas. |
| A quick visual of an already-rendered local form | Capture the live form after testing its controls and browsers. |
| A server-side or scheduled URL capture | Use a browser-based service such as ScreenshotNeo instead of trying to run html2canvas in Node.js. |
Frequently Asked Questions
Can I capture only one field or section?
Yes. Pass that field’s containing DOM element to html2canvas; the library captures the supplied element rather than requiring the whole page.
Should I store the generated data URL?
For large images, prefer converting the canvas to a Blob and uploading it or creating an object URL, because a data URL keeps the entire encoded image in a string.
Does preventing the default submit send the form?
No. It stops the browser navigation. If your application still needs server submission, send the collected data separately with your chosen request flow.
Quick Recap
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.

