October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
JavaScript

How to Capture Leaflet SVG Vector Layers as PNG with PhantomJS 1.9

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

Use PhantomJS 1.9 to render the finished Leaflet page, then call page.render('map.png'). A direct page capture preserves Leaflet’s rendered SVG paths (and Canvas layers) because PhantomJS uses a WebKit layout and rendering engine. Set the viewport first, wait until tiles and vectors are ready, and use clipRect only when you need a crop. If your export library rasterizes through Canvas instead, switch the relevant Leaflet layers to Canvas and satisfy image CORS requirements.

The reliable decision: direct page capture or Canvas export?

There are two different capture pipelines, and confusing them is the usual reason vector paths disappear.

Pipeline SVG paths HTML controls and markers Main constraints Best use
PhantomJS page.render() Included as rendered SVG Included when visible in the page Map must finish loading before render; viewport and crop determine output A faithful screenshot of the complete Leaflet page
leaflet-image or another Canvas exporter Only after the layers are rendered to Canvas HTML-only features such as L.divIcon, zoom controls and legends are not rasterized Tile and marker images must be CORS-compatible A map-only bitmap assembled from Canvas content

Leaflet 1.9.4 uses SVG as the default renderer for path layers. Setting preferCanvas: true changes the map’s default renderer, while renderer: L.canvas() opts an individual path into Canvas. That setting is necessary for a Canvas exporter, not for a direct PhantomJS screenshot: PhantomJS can capture SVG as part of the page.

Prepare the Leaflet page before PhantomJS opens it

Give the map a real size

The map container must have a non-zero width and height before Leaflet initializes. A zero-height container produces an apparently blank capture even though the JavaScript ran.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • 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
<style>
  html, body { margin: 0; width: 100%; height: 100%; }
  #map { width: 1280px; height: 800px; }
</style>
<div id="map"></div>

Keep SVG for a direct screenshot

var map = L.map('map').setView([51.505, -0.09], 13);

var tiles = L.tileLayer('https://your-tile-host/{z}/{x}/{y}.png', {
  attribution: 'Map data provider attribution'
}).addTo(map);

var line = L.polyline([
  [51.505, -0.09],
  [51.51, -0.10],
  [51.515, -0.085]
], { color: '#1769aa', weight: 4 }).addTo(map);

var area = L.polygon([
  [51.50, -0.08],
  [51.51, -0.06],
  [51.52, -0.08]
], { color: '#b22', fillOpacity: 0.25 }).addTo(map);

Those paths use Leaflet’s SVG renderer by default. A direct page render captures their SVG elements together with the basemap and any visible HTML UI.

Use Canvas only when the exporter requires it

var map = L.map('map', { preferCanvas: true }).setView([51.505, -0.09], 13);
var line = L.polyline(coords, { renderer: L.canvas() }).addTo(map);

Use the map-wide option when most paths go through a Canvas exporter, or set renderer: L.canvas() on each layer that must be exported. Leaflet describes vector layers as geographic coordinates transformed into pixels and drawn by either SVG or Canvas; changing the renderer changes where those pixels are produced.

Distinguish ordinary paths from SVGOverlay

An ordinary polyline, polygon or circle is a vector path managed by Leaflet. SVGOverlay is a separate layer type: it binds an SVG element to geographic bounds. Both can appear in a direct page screenshot, but code that searches only for ordinary path layers will not automatically handle an SVG overlay. Test the overlay in the actual page you intend to capture.

Keep provider attribution and access rules intact

Tile selection is independent of the PNG call. Retain the tile provider’s required attribution in the page and follow its usage policy. OpenStreetMap tiles, for example, require attribution. A screenshot does not remove that obligation.

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

Tell PhantomJS exactly when the map is ready

A fixed sleep can work as a demonstration, but it is a race: a busy tile server or a slow vector request may still be drawing when the timer expires. Have the page set a readiness flag after your own data, overlays and tiles have settled, then poll that flag from PhantomJS.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • 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
// map.html, after your application has added paths and overlays
var pendingData = fetch('/routes.json')
  .then(function (r) { return r.json(); })
  .then(function (routes) {
    routes.forEach(function (route) {
      L.polyline(route.coordinates, { color: route.color }).addTo(map);
    });
  });

var tileReady = new Promise(function (resolve) {
  tiles.once('load', resolve);
});

Promise.all([pendingData, tileReady]).then(function () {
  // Set this only after every layer that should appear in the image is added.
  window.mapReady = true;
});

If your app loads tiles from several layers or receives overlays through callbacks, include all of those completion events in the readiness condition. For a static page, setting window.mapReady = true immediately after the final layer is added is sufficient.

Capture the page as PNG with PhantomJS 1.9

This complete script opens the page, checks the load status, waits for window.mapReady, and renders a PNG. The polling timeout prevents a broken page from hanging the process forever.

var page = require('webpage').create();
var system = require('system');

page.viewportSize = { width: 1280, height: 800 };
// Optional crop inside the viewport:
// page.clipRect = { top: 0, left: 0, width: 1280, height: 800 };

var url = system.args[1] || 'http://localhost/map.html';
var deadline = Date.now() + 30000;

page.open(url, function (status) {
  if (status !== 'success') {
    console.log('page failed to load');
    phantom.exit(1);
    return;
  }

  function checkReady() {
    var ready = page.evaluate(function () {
      return window.mapReady === true;
    });

    if (ready) {
      page.render('map.png', 'PNG');
      phantom.exit(0);
      return;
    }

    if (Date.now() > deadline) {
      console.log('map did not become ready before the timeout');
      phantom.exit(2);
      return;
    }

    window.setTimeout(checkReady, 100);
  }

  checkReady();
});

Run it with a local page URL:

phantomjs capture.js http://localhost/map.html

page.viewportSize controls the browser’s layout size and therefore the natural screenshot dimensions. Set page.clipRect when you need a specific rectangle rather than the complete viewport. PhantomJS documentation lists PNG as a supported output and documents both properties for capture sizing.

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

When a short delay is unavoidable

The minimal pattern often shown in examples is a one-second timeout after page.open. Treat that as sequencing syntax, not a guarantee that tiles or vectors are ready. A page-owned readiness signal is safer because it follows the actual asynchronous work.

If you use leaflet-image, make the renderer and assets compatible

leaflet-image exports through Canvas. A map whose paths remain SVG can therefore produce a bitmap with the basemap but no vector geometries. Initialize the map with Canvas or pass a Canvas renderer to every path that matters:

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • 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.
var map = L.map('map', { preferCanvas: true }).setView([51.505, -0.09], 13);
var route = L.polyline(coords, {
  renderer: L.canvas(),
  color: '#1769aa'
}).addTo(map);

// After tile and layer loading has completed:
leafletImage(map, function (error, canvas) {
  if (error) {
    console.error(error);
    return;
  }
  canvas.toBlob(function (blob) {
    // Save blob as PNG in your application.
  }, 'image/png');
});

Canvas exporter requirements

  • Tile images and marker images must permit the cross-origin access required by the exporter. A CORS failure can taint the Canvas and prevent export.
  • HTML-based features are outside the Canvas rasterization: L.divIcon markers, zoom controls, legends and other DOM elements will not appear.
  • Confirm every vector layer is actually added before calling the exporter; renderer settings do not export a layer that was never created.

If you need controls, legends or HTML markers in the final image, direct PhantomJS page capture is the more faithful path. If the page contains very heavy vector data, test Canvas rendering; Leaflet’s FAQ notes that switching from SVG to Canvas may help considerably, depending on the application and data.

Troubleshoot missing or incorrect PNG content

Paths are missing, but the basemap is visible

  • For a direct PhantomJS render, inspect the page first and confirm the paths were added before mapReady becomes true.
  • For leaflet-image, set preferCanvas: true or assign renderer: L.canvas() to each required path.
  • Check that your selector or data callback did not create the layer after the exporter ran.

The image is blank or the basemap is incomplete

  • Verify tile URLs in the PhantomJS page and open the same URL in a browser.
  • Wait for the tile layer’s load event (and any additional tile layers) before rendering.
  • For Canvas export, fix CORS headers or use tile and marker sources that explicitly support cross-origin use.
  • Confirm the map container has explicit dimensions before Leaflet initializes.

Controls, legends or HTML markers are absent

That is expected with a Canvas exporter. Use direct PhantomJS page capture if those DOM elements belong in the PNG, or recreate them as Canvas/SVG content before export.

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

The output dimensions are wrong

Set page.viewportSize before page.open. Use clipRect for a deliberate crop. Remember that changing the viewport can trigger responsive CSS and alter the map layout.

The script exits before drawing finishes

Replace a guessed delay with the application readiness flag. Include asynchronous route loads, tile layers, image overlays and any animation you want captured. If an animation should not appear, disable it and set the flag only after the final static frame is rendered.

Heavy geometry renders slowly

Try Canvas for the path layers and compare the result with SVG. Canvas can improve handling of heavy vector data, but it also introduces CORS and HTML-element limitations. There is no universal performance figure; measure the specific map and data set.

Rank #4
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • 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

Reliability, sizing and operational notes

  • Deterministic output: fix the viewport, zoom, center, device-dependent CSS and readiness condition. Avoid capturing while a map is panning or zooming.
  • Network failures: treat a missing tile or data response as an application error and report it before calling page.render; otherwise you may save a valid-looking but incomplete PNG.
  • Security: do not embed credentials in a public map page. If a tile or API service requires authentication, configure the page through your server-side capture environment.
  • Attribution: keep required provider credit visible in the captured page, especially when the PNG will be redistributed.
  • Cost: PhantomJS itself does not define tile-provider charges. Your tile, geocoding and data-service terms remain separate from the screenshot step.
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 returns a PNG, JPEG, WebP or PDF, so you can send the map URL instead of maintaining a PhantomJS process. It removes cookie banners, newsletter popups and chat widgets before the shot; bot checks, blank pages and failed loads are not billed; and its MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf.

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

See the ScreenshotNeo API documentation for URL parameters and response headers. Replace the example URL with the publicly reachable page containing your Leaflet map.

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}`);

ScreenshotNeo supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks, selector or network-idle waits, request blocking, headers, cookies, user agents, Authorization, timezone and geolocation. It also offers transparent backgrounds, resizing, caller-selected cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting and an OpenAPI specification. Parameters used by other screenshot APIs are accepted to ease migration.

Plan Included shots Price
Free 1,000 per month $0; no card
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Every feature is available on every plan, and yearly billing provides two months free. Start with 1,000 free screenshots a month with no card, then choose a paid plan starting at $5 for 3,000 shots if your capture volume requires it.

FAQ

Can PhantomJS capture an inline SVG overlay as well as Leaflet paths?

Yes, when the overlay is rendered in the page and lies inside the captured viewport. An SVGOverlay is still a different Leaflet API, so make sure its bounds and insertion callback have completed before your readiness flag is set.

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

Should I convert every map to Canvas?

No. Convert when the export pipeline is Canvas-based or when testing shows heavy geometry benefits. For a direct PhantomJS screenshot, retaining SVG avoids the Canvas exporter’s CORS and HTML-element restrictions.

Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【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.

Why does a successful HTTP load still produce an incomplete map?

page.open reports the document load, not the completion of later tile, data and overlay requests. Gate rendering on an application-level ready signal that includes those asynchronous operations.

Frequently Asked Questions

Can PhantomJS capture an inline SVG overlay as well as Leaflet paths?

Yes, when the overlay is rendered in the page and lies inside the captured viewport. An SVGOverlay is a different Leaflet API, so include its completion in your readiness signal.

Should I convert every map to Canvas?

No. Convert when the export pipeline is Canvas-based or testing shows heavy geometry benefits. Direct PhantomJS capture can retain SVG without Canvas exporter restrictions.

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

Why does a successful HTTP load still produce an incomplete map?

page.open reports document load, not completion of later tile, data and overlay requests. Render only after your application-level ready signal is true.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.