To capture a Leaflet map with html2canvas, give the map a real height, configure the tile layer for CORS, wait for every tile and overlay to finish loading, then render the map element and export the returned canvas. A working capture can be as small as html2canvas(document.querySelector('#map'), { useCORS: true }), but cross-origin tiles, timing, browser canvas limits and Leaflet layers determine whether the result is complete.
What you need before capturing
Install or load Leaflet and html2canvas in the page that contains the map. The map element must have a non-zero width and height; Leaflet’s quick-start pattern assigns a concrete height in CSS. Without it, the map may initialize into a zero-height box and html2canvas has nothing useful to render.
#map {
width: 100%;
height: 480px;
}
Your tile provider must permit the browser to read tile pixels. Keep the provider’s attribution visible in the map and follow its production, token, referrer and usage rules. Leaflet supplies the map engine, not imagery; you choose a tile service and are responsible for its terms.
A complete browser example
The following page creates a map, waits until visible tiles settle, captures only the map container and downloads a PNG. Replace the tile URL and attribution with a provider you are authorized to use.
#1 Best Overall
- Bright, high-resolution 5” glass capacitive touchscreen display lets you easily view your route
- Get more situational awareness with alerts for school zones, speed changes, sharp curves and more
- View food, fuel and rest areas along your active route, and see upcoming cities and milestones
- View Tripadvisor traveler ratings for top-rated restaurants, hotels and attractions to help you make the most of road trips
- Directory of U.S. national parks simplifies navigation to entrances, visitor centers and landmarks within the parks
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<div id="map"></div>
<button id="download-map" type="button">Download map PNG</button>
<script>
const map = L.map('map', {
preferCanvas: true
}).setView([51.505, -0.09], 13);
const tiles = L.tileLayer('https://your-tile-host/{z}/{x}/{y}.png', {
crossOrigin: true,
attribution: '© Your tile provider'
}).addTo(map);
L.marker([51.505, -0.09]).addTo(map).bindPopup('Central point');
function waitForTiles(layer) {
return new Promise((resolve) => {
if (layer.getContainer() && layer._tilesToLoad === 0) {
resolve();
return;
}
let finished = false;
const done = () => {
if (!finished) {
finished = true;
resolve();
}
};
layer.once('load', done);
// Avoid waiting forever if a provider leaves one request pending.
setTimeout(done, 15000);
});
}
async function downloadMap() {
map.invalidateSize();
await waitForTiles(tiles);
// Let marker, popup and other DOM overlays paint for one frame.
await new Promise(requestAnimationFrame);
const mapEl = document.querySelector('#map');
const canvas = await html2canvas(mapEl, {
useCORS: true,
backgroundColor: null,
scale: window.devicePixelRatio,
logging: false,
ignoreElements: (element) => element.classList.contains('leaflet-control')
});
const link = document.createElement('a');
link.download = 'leaflet-map.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
document.querySelector('#download-map').addEventListener('click', downloadMap);
</script>
The private _tilesToLoad property is useful as a quick guard but is not a stable public API. For production code, the load event plus a timeout is safer than depending on an internal field. If your application adds data asynchronously, await that work as well before calling html2canvas.
How the capture options affect the output
Make cross-origin tiles readable
Set Leaflet’s tile-layer crossOrigin option (usually true, or the exact string required by your provider) and set html2canvas’s useCORS: true. Both settings are necessary but neither can grant permission. Each tile response must include a compatible Access-Control-Allow-Origin header. Inspect the browser Network panel to verify the header on the image requests.
If a tile server does not send that header, the canvas becomes tainted when the image is drawn. A tainted canvas cannot be safely read with toDataURL() or toBlob(). Use a same-origin server proxy that adds appropriate CORS headers, or select a tile provider that explicitly supports browser pixel access. allowTaint: true does not make a tainted canvas exportable and is not a universal fix.
Keep or remove controls
html2canvas reconstructs the map from DOM styles and elements. If you want a map-only image, remove controls before capture or mark them with data-html2canvas-ignore. You can also use ignoreElements, as in the example. Do not hide the provider’s required attribution in the exported image unless its terms expressly allow that.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallRank #2
- 6” high-resolution navigator includes map updates of North America
- Hands-free calling when paired with your compatible smartphone with BLUETOOTH technology and convenient Garmin voice assist lets you ask for directions to places you want to go
- Road trip–ready features include the HISTORY database of notable sites, a U.S. national parks directory, Tripadvisor traveler ratings and millions of Foursquare POIs
- Driver alerts for things such as school zones, sharp curves and speed changes help encourage safer driving and increase situational awareness
- Access live traffic, fuel prices, parking, weather and smart notifications when you pair this navigator with your compatible smartphone running the Garmin Drive app
Retina sharpness and canvas limits
scale: window.devicePixelRatio produces a sharper image on high-density screens, but it multiplies the canvas dimensions and memory required. Very large full-page maps can exceed browser canvas limits, fail silently or be clipped. Reduce scale, the map dimensions or the requested crop when that happens.
Crop an area or force a fixed size
For a crop, pass coordinates and dimensions to html2canvas. Coordinates are relative to the element being captured.
const cropped = await html2canvas(document.querySelector('#map'), {
useCORS: true,
x: 40,
y: 20,
width: 900,
height: 500,
scale: 1
});
For predictable output, set the map element to the desired CSS width and height before capture, then use matching width and height options. If a scrollable map is clipped, align windowWidth and windowHeight with the element’s scroll dimensions, or capture a smaller region.
Waiting for tiles, overlays and lazy content
An immediate call often captures gray or partly empty tiles because Leaflet requests images asynchronously. Listen for the tile layer’s load event, wait for application overlays (markers, GeoJSON, popups and labels), and give the browser a paint frame before rendering.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
- Explore confidently with the reliable handheld GPS
- 2.2” sunlight-readable color display with 240 x 320 display pixels for improved readability
- Preloaded with Topo Active maps with routable roads and trails for cycling and hiking
- Support for GPS and GLONASS satellite systems allows for tracking in more challenging environments than GPS alone
- 8 GB of internal memory for map downloads plus a micro SD card slot
- Call
map.invalidateSize()after showing a map in a modal, tab or accordion. - Wait for every data fetch that creates markers or vector layers.
- Open a popup first if it belongs in the image, then wait one or two animation frames.
- Use a timeout so one failed tile cannot block the export forever; investigate that failed request separately.
For pages with lazy-loaded imagery or custom overlays, trigger the same scrolling or data-loading steps a user would perform before capture. html2canvas only sees content present in the DOM at capture time.
What html2canvas can and cannot reproduce
html2canvas does not take a literal browser screenshot; it builds a representation from properties it reads from the DOM. This distinction explains many differences between the visible map and the exported image.
| Map content | Typical result | What to do |
|---|---|---|
| Leaflet tile images with valid CORS | Usually rendered and exportable | Use crossOrigin and useCORS; verify response headers |
| Cross-origin tiles without CORS | Canvas may be tainted or tiles omitted | Use a same-origin proxy or another permitted provider |
| HTML controls and DOM labels | Often reconstructed | Keep them, or exclude with data-html2canvas-ignore/ignoreElements |
| SVG vector layers | Depends on SVG and CSS support | Test your styling; simplify unsupported effects |
| Canvas-rendered vectors | Generally more reliable for map exports | Use renderer: L.canvas() or preferCanvas: true where appropriate |
| Cross-origin iframes | Not readable by the page | Render the content in your own document or use a server-side browser |
| Already-tainted canvases | Unreadable during export | Fix the original image CORS chain; a later option cannot untaint it |
HTML controls and HTML-based L.divIcon content are not rasterized by the separate leaflet-image exporter; if you use that exporter for a vector-focused workflow, choose Canvas rendering for layers that must appear. html2canvas itself may reproduce DOM-based icons, but you should verify complex CSS and fonts in your target browsers.
Downloading formats other than PNG
PNG preserves transparency and is the simplest lossless export:
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #4
- 8” navigator with high-resolution, dual-orientation display and map updates of North America .Special Feature:Large Display; Voice Assist; Hands-Free Calling; Live Traffic and Weather; Traffic Cams and Parking; Smart Notifications,Driver Alerts; Tripadvisor; National Parks Directory; Find Places by Name; Garmin Real Directions Feature.
- Hands-free calling when paired with your compatible smartphone with BLUETOOTH technology and convenient Garmin voice assist lets you ask for directions to places you want to go
- Road trip–ready features include the HISTORY database of notable sites, a U.S. national parks directory, Tripadvisor traveler ratings and millions of Foursquare POIs
- Driver alerts for things such as school zones, sharp curves and speed changes help encourage safer driving and increase situational awareness
- Access live traffic, fuel prices, weather, parking and smart notifications when you pair this navigator with your compatible smartphone running the Garmin Drive app
canvas.toBlob((blob) => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'map.png';
a.click();
URL.revokeObjectURL(url);
}, 'image/png');
For a smaller photographic-style file, request JPEG and supply a quality value. JPEG has no transparency, so set a solid background first.
const jpg = canvas.toDataURL('image/jpeg', 0.9);
Common failures and precise fixes
Gray, missing or partial tiles
- Cause: capture ran before tile loading completed. Fix: await the layer’s
loadevent and your overlay promises. - Cause: the map was hidden or resized. Fix: display it, call
map.invalidateSize(), then capture. - Cause: requests failed or were rate-limited. Fix: inspect Network responses, provider status and required tokens.
“Tainted canvases may not be exported”
A tile, marker image or other bitmap came from an origin that did not authorize pixel access. Confirm Access-Control-Allow-Origin on every image response, configure Leaflet’s crossOrigin, and remove or proxy the non-CORS asset. Do not rely on allowTaint.
The map is clipped or unexpectedly scaled
Check the element’s computed width and height, its scroll dimensions, device-pixel scale and browser canvas limits. Capture a smaller region, lower scale, or set explicit dimensions rather than relying on a responsive viewport.
Markers or popups are absent
Wait until the marker layer exists and the popup is open. For custom icons, verify their image URLs and CORS headers. For vectors, try Canvas rendering and avoid unsupported CSS effects.
Best Value
- Bright, high-resolution 5” glass capacitive touchscreen display lets you easily view your route
- Get more situational awareness with alerts for school zones, speed changes, sharp curves and more
- View food, fuel and rest areas along your active route, and see upcoming cities and milestones
- View Tripadvisor traveler ratings for top-rated restaurants, hotels and attractions to help you make the most of road trips
- Directory of U.S. national parks simplifies navigation to entrances, visitor centers and landmarks within the parks
Fonts, shadows or CSS look different
This is a DOM reconstruction limitation, not necessarily a Leaflet bug. Ensure fonts are loaded before capture, simplify unsupported CSS, and compare output in the browsers you support.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When a browser capture is the wrong tool
html2canvas is convenient for a user-triggered export in the same page, but it inherits browser memory limits, CORS policy and whatever state the user currently sees. A server-side renderer is a better fit for scheduled reports, many URLs, consistent viewport settings, authenticated pages or maps containing third-party frames. You still need permission to use the imagery and must preserve required attribution.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One request renders a URL and returns PNG, JPEG, WebP or PDF. Its cleaning steps accept cookie/consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result.
For a public map page, the one-call cURL form is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for options such as full-page capture with lazy images, CSS-selector element capture, device presets, retina scale, custom JavaScript, waits, request blocking, cookies, headers, timezone, geolocation, transparent backgrounds, resizing, caching, signed links, asynchronous jobs, webhooks and bulk capture.
Recommended Free Tools
Equivalent Python request
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Equivalent Node.js request
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
An MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf. Every plan includes every feature. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
Practical choice checklist
- Choose html2canvas for an in-page, user-visible export where you control the map and tile CORS.
- Choose a proxy when a permitted tile provider lacks browser CORS but server retrieval is allowed.
- Choose Canvas-rendered vectors when SVG or HTML layer fidelity is unreliable.
- Choose a server-side screenshot for repeatable automation, many pages or browser-only content.
- In every case, retain attribution and comply with the imagery provider’s production policy.
FAQ
Can I capture a map before it is visible on screen?
Yes, but give its container dimensions and call map.invalidateSize() after it becomes laid out. Capturing a display:none element generally produces an empty or incorrect result.
Does html2canvas create a geospatially accurate map image?
No. It creates a visual rendering of the current DOM, not a GIS export with projection metadata, selectable features or a guaranteed scale. Use a dedicated mapping export pipeline when those properties matter.
Why does a screenshot service avoid my page’s CORS problem?
A service renders the page in its own browser environment rather than asking your browser canvas to read every cross-origin bitmap. The target page and imagery still need to load successfully and remain within their providers’ terms.
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 →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.

