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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

If images disappear from an html2canvas export in a React app, check whether they come from another origin. For a cross-origin image to remain readable in the exported canvas, its server must grant CORS permission and html2canvas must attempt a CORS request with useCORS: true. If you cannot configure the image host, use a controlled proxy for assets your app is authorized to retrieve. allowTaint: true does not make a tainted canvas downloadable.

Why aren’t my images rendered?

A browser can display an image from another origin while still preventing JavaScript from reading the image’s pixels. When an image loaded without CORS approval is drawn into a canvas, the browser marks that canvas as tainted. The pixels may appear on screen, but calls such as toBlob() or toDataURL() cannot export them; they raise a SecurityError. MDN explains this rule in its guide to using cross-origin images in a canvas.

React does not change browser CORS or canvas security rules. html2canvas reconstructs a rendering from DOM information rather than taking a native pixel-perfect browser screenshot, and it cannot bypass browser content policies. Its FAQ states that “html2canvas cannot circumvent content policy restrictions set by your browser.”

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

There are two separate requirements for the common direct-loading fix: the image server must return a suitable Access-Control-Allow-Origin response header, and html2canvas must be configured to try loading the image in CORS mode. The client-side option cannot grant permission that the server has not provided.

How to capture and download a React element

Install html2canvas if it is not already in the project, then call it after the target element has mounted. This example uses a button handler and downloads a PNG when the capture is clean:

import html2canvas from 'html2canvas';

async function downloadCapture(element) {
  if (!element) throw new Error('Capture element is not mounted');

  const canvas = await html2canvas(element, {
    useCORS: true,
  });

  const blob = await new Promise((resolve, reject) => {
    canvas.toBlob((result) => {
      if (result) resolve(result);
      else reject(new Error('Canvas could not be encoded as PNG'));
    }, 'image/png');
  });

  const link = document.createElement('a');
  const objectUrl = URL.createObjectURL(blob);
  link.href = objectUrl;
  link.download = 'capture.png';
  link.click();
  URL.revokeObjectURL(objectUrl);
}

// In a React component, pass the current ref after mount:
// <button onClick={() => downloadCapture(captureRef.current)}>
//   Download
// </button>

For a component, attach a React ref to the exact region to capture, and invoke the function from an event handler after rendering. The html2canvas configuration reference documents useCORS and other capture options. The code shows the export flow; actual success depends on every included image being loaded in a way that leaves the canvas origin-clean.

Fix a remote image when you control its host

  1. Identify the failing image. Compare its full origin—scheme, hostname, and port—with the page’s origin. Use browser developer tools to inspect the image request and response and look for CORS errors. A same-origin asset, a data: URL, and a remote cross-origin URL do not follow the same path.
  2. Configure the image origin or CDN. It should return Access-Control-Allow-Origin permitting your application’s origin. A wildcard value may be suitable only when the asset and credential model allow it; do not use it as a blanket substitute for an intentional access policy.
  3. Set useCORS: true in the html2canvas call. This tells the library to attempt CORS loading. It does not fix a missing, malformed, or disallowing response header.
  4. Retry the capture and inspect the output. If the image still fails, check the response headers actually returned for that URL, including any CDN behavior or redirect, rather than assuming the application option changed the server response.

If the image is loaded elsewhere in the React app through an <img> element, its crossOrigin="anonymous" attribute affects the browser’s request mode, but it must still be paired with server permission. Adding that attribute alone cannot make a server that sends no permissive CORS header authorize the image. For html2canvas captures, the relevant library setting is useCORS: true. MDN’s CORS-enabled image guidance describes the browser-side rule.

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

When to use a controlled proxy

If you cannot change the image host’s CORS configuration, html2canvas documents a proxy option. A server you control can retrieve an authorized image and serve it to the app from the same origin, avoiding the browser’s cross-origin read restriction for that response. See the project’s getting-started guide for its proxy approach.

A proxy adds security and operational work. It must not become an unrestricted endpoint that fetches arbitrary URLs on a caller’s behalf. Restrict destinations to approved hosts or resources, validate input, constrain response size and request duration, handle redirects deliberately, and return the correct content type. Fetch only resources your application is authorized to retrieve. Authentication requirements, hotlink protections, redirects, and the remote host’s policies can still prevent retrieval.

When you configure the html2canvas call to use a proxy, provide the URL of your restricted server endpoint through the documented proxy option. The exact endpoint implementation depends on your server framework and authorization model; html2canvas’s documented proxy pattern accepts a URL parameter and returns image content through the same origin. Do not deploy a generic URL-fetching route copied without destination and resource limits.

Which remedy fits your situation?

Remedy Best when What is required Trade-off
Configure the image host and use useCORS: true You own the image origin or can request a change from its operator. A response header permitting the app’s origin, plus the html2canvas CORS option. Direct and avoids proxy infrastructure, but the host configuration must be correct.
Controlled same-origin proxy The host cannot be configured and your app is allowed to retrieve the image. A restricted server endpoint and html2canvas proxy configuration. Adds server operations and security responsibilities; it does not override the remote host’s access policy.
Exclude the image or use an authorized same-origin copy Neither direct CORS access nor a safe proxy is available. Change the captured content or serve an approved copy from your own origin. The capture no longer includes the original remote image unless a permitted copy is available.

Do not choose allowTaint: true as an export workaround. It can permit drawing content that would otherwise be skipped, but it does not make the browser permit pixel extraction. A tainted canvas is incompatible with reliable image downloading.

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

How do I handle cross-origin images? Troubleshooting

The image is visible in the page but missing in the downloaded capture

Visibility in the DOM does not prove canvas readability. Inspect the image response for an Access-Control-Allow-Origin header that permits the page, and verify that the capture uses useCORS: true. If you cannot change the host, consider a restricted proxy for an image you are permitted to fetch.

The image is missing even though I set useCORS: true

The option only asks html2canvas to use CORS; it cannot supply server permission. Check the actual response headers and any redirects. Also confirm that the target image is genuinely cross-origin: a failed same-origin request, broken URL, or unrelated loading error needs a different fix.

Adding crossOrigin="anonymous" did not fix the capture

The attribute changes how the browser requests an image; it does not change the remote server’s response. The server still needs to grant permission. For html2canvas itself, set useCORS: true on the capture call as well.

toBlob() or toDataURL() raises a security error

The canvas is likely tainted by content drawn without CORS approval. Find the offending resource and obtain it through an approved CORS response, a properly restricted same-origin proxy, or exclude it. Switching to allowTaint: true will not make export readable. MDN documents that reading or exporting a tainted canvas raises SecurityError in its canvas CORS guide.

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

Images fail or appear incomplete without a CORS error

Treat this as a resource-loading or timing problem rather than a CORS fix. Confirm the image has loaded before capture and inspect the browser console and network panel. html2canvas configuration includes imageTimeout and an onError callback for failed resources; those can help diagnose or manage failures, but do not grant CORS permission. For clipping related to very large captures, the project FAQ recommends matching windowWidth and windowHeight to the scroll dimensions.

Performance, reliability, and practical limits

Every image in the captured region matters, not just the image that prompted the error. A single disallowed cross-origin asset can prevent the export from being origin-clean. Make the capture region as deliberate as possible, and avoid treating a successful render on screen as proof that the export will succeed.

Large captures also have practical browser canvas limits. html2canvas’s FAQ notes viewport-dimension settings as relevant to clipping cases, but increasing dimensions is not a general remedy for CORS failures. Likewise, waiting longer or setting an image timeout can address some load timing problems, not a server’s refusal to authorize cross-origin use. The project’s examples and configuration reference show available capture controls.

For a screenshot of a public web page rather than a custom React-rendered region, ScreenshotNeo is a separate server-side option: its API captures a URL, rather than exporting the current client canvas. That distinction matters if your goal is specifically to preserve unsaved, user-specific, or locally rendered React state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a screenshot of a URL, rather than downloading a particular DOM element from your running React app, ScreenshotNeo takes a page URL in one GET request and returns an image or PDF. Its clean-shot flow accepts cookie or consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers indicate the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients.

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

Replace the target URL with the page you want and provide your API key. See the ScreenshotNeo API documentation for setup and supported parameters. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000. The service is for URL-based captures, not a way to export arbitrary in-memory React state.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month with no card.

Further reading

Frequently Asked Questions

Does a CORS error in this workflow mean React is blocking the image?

No. React is the framework rendering the DOM, but the restriction is enforced by browser cross-origin and canvas security rules.

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

Can html2canvas produce a pixel-perfect screenshot of the browser?

No. It reconstructs content from DOM information; it is not a native browser screenshot mechanism.

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.