docs/plugins.md
While Leaflet is meant to be as lightweight as possible, and focuses on a core set of features, an easy way to extend its functionality is to use third-party plugins. Thanks to the awesome community behind Leaflet, there are literally hundreds of nice plugins to choose from.
The following plugins allow loading different maps and provide functionality to tile and image layers.
Ready-to-go basemaps, with little or no configuration at all.
{% include plugin_category_table.html category="basemap-providers" %}
Plugins for loading basemaps or GIS raster layers in common (albeit non-default) formats.
{% include plugin_category_table.html category="basemap-formats" %}
Sometimes you don't want to load a map, just big custom images. Really big ones.
{% include plugin_category_table.html category="non-map-base-layers" %}
The following plugins change the way that tile or image layers are displayed in the map.
{% include plugin_category_table.html category="tile-image-display" %}
The following plugins change the way that tile layers are loaded into the map.
{% include plugin_category_table.html category="tile-load" %}
Plugins to display vector tiles.
{% include plugin_category_table.html category="vector-tiles" %}
The following plugins provide new ways of loading overlay data (GIS vector data): points, lines and polygons.
Load your own data from various GIS formats.
{% include plugin_category_table.html category="overlay-data-formats" %}
Load dynamic data which is updated in the map, or load GIS vector data in non-standard ways.
{% include plugin_category_table.html category="dynamic-custom-data-loading" %}
These plugins create useful overlays from scratch, no loading required.
{% include plugin_category_table.html category="synthetic-overlays" %}
Load overlay data from third-party-services. See also basemap providers and plugin collections.
{% include plugin_category_table.html category="data-providers" %}
The following plugins provide new ways of displaying overlay data information.
These plugins provide new markers or news ways of converting abstract data into images in your screen. Leaflet users versed in GIS also know these as symbolizers.
{% include plugin_category_table.html category="markers-renderers" %}
These plugins animate markers or some geometries. See also geometries with time or elevation.
{% include plugin_category_table.html category="overlay-animations" %}
When you are displaying a lot of data, these plugins will make your map look cleaner.
{% include plugin_category_table.html category="clustering-decluttering" %}
These plugins create heatmaps and heatmap-like visualizations from vector data.
{% include plugin_category_table.html category="heatmaps" %}
Powerful multi-purpose libraries for data visualization.
{% include plugin_category_table.html category="dataviz" %}
The following plugins enable users to interact with overlay data: edit geometries, select areas or features, interact with the time dimension, search features and display information about them.
Allows users to create, draw, edit and/or delete points, lines and polygons.
{% include plugin_category_table.html category="edit-geometries" %}
Most data is two-dimensional (latitude and longitude), but some data has more dimensions (altitude and/or time). The following plugins help users navigate these extra dimensions.
{% include plugin_category_table.html category="time-elevation" %}
Plugins that search for overlays and enhance how to display information about them.
{% include plugin_category_table.html category="search-popups" %}
These plugins help users select either overlays or areas in the map.
{% include plugin_category_table.html category="area-overlay-selection" %}
New ways to interact with the map itself.
The following plugins enhance or extend LayersControl.
{% include plugin_category_table.html category="layer-switching-controls" %}
Change the way the user can interactively move around the map.
{% include plugin_category_table.html category="interactive-pan-zoom" %}
Change the way the user is moved around the map, by jumping to predefined/stored places.
{% include plugin_category_table.html category="bookmarked-pan-zoom" %}
Allows display of the map in full-screen mode.
{% include plugin_category_table.html category="fullscreen-controls" %}
Display two maps at once. One of them might be a different size and zoom level, usable as a minimap to aid with navigation.
{% include plugin_category_table.html category="minimaps-synced-maps" %}
Allow the user to measure distances or areas.
{% include plugin_category_table.html category="measurement" %}
Show the geographical coordinates under the mouse cursor in different ways.
{% include plugin_category_table.html category="mouse-coordinates" %}
These plugins extend Leaflet event handling.
{% include plugin_category_table.html category="events" %}
Buttons, sliders, toolbars, sidebars, and panels.
{% include plugin_category_table.html category="user-interface" %}
Print or export your map.
<!-- - Saving a Leaflet Map to a PNG Example using Javascript and PHP https://github.com/tegansnyder/Leaflet-Save-Map-to-PNG - Get a PNG from a Leaflet map and export it in PDF https://github.com/chrissom/leaflet-pdf -->{% include plugin_category_table.html category="print-export" %}
Plugins that extend Leaflet's geolocation capabilities.
{% include plugin_category_table.html category="geolocation" %}
The following plugins perform several sorts of geoprocessing (mathematical and topological operations on points, lines and polygons).
{% include plugin_category_table.html category="geoprocessing" %}
The following plugins use external services to calculate driving or walking routes.
{% include plugin_category_table.html category="routing" %}
External services that transform an address or the name of a place into latitude and longitude (or vice versa).
{% include plugin_category_table.html category="geocoding" %}
Sets of plugins that span several categories.
Plugin developers: please keep future plugins in individual repositories.
{% include plugin_category_table.html category="plugin-collections" %}
Ease your development integrating Leaflet into a development framework or automating some of the javascript/CSS work for complex applications.
{% include plugin_category_table.html category="frameworks-build-systems" %}
The following plugins integrate Leaflet into third party services or websites.
{% include plugin_category_table.html category="3rd-party-integration" %}
Leaflet keeps it simple. If you can think of a feature that is not required by all Leaflet users, and you can write the JavaScript code in a reusable way, you've got yourself a Leaflet plugin already.
There are no hard requirements on how to create your own plugin, but all developers are encouraged to read the recommendations in the plugin guide.
Once your plugin is ready, you can submit it: just send a pull request with a new plugin file in /docs/_plugins/to our GitHub repository.
<script> function loadRepoData() { const regexpGithubCom = /^https?:\/\/(?:www\.)?github\.com\/([\w\d-_.]+)\/([\w\d-_.]+)\/?/; const regexpGithubIO = /^https?:\/\/([\w\d-_.]+)\.github\.io\/([\w\d-_.]+)\/?/; const regexpGitlabCom = /^https?:\/\/(?:www\.)?gitlab\.com\/([\w\d-_.]+)\/([\w\d-_.]+)\/?/; const rows = document.querySelectorAll('table.plugins tr'); rows.forEach((row) => { try { const repoData = row.querySelector('.repo-data'); if (repoData) { const link = row.querySelector('.plugin-repo-url').href; let badges = []; const matchGithubCom = link.match(regexpGithubCom); if (matchGithubCom) { const repo = `${matchGithubCom[1]}/${matchGithubCom[2]}`; badges = [ `https://badgen.net/github/stars/${repo}`, `https://badgen.net/github/last-commit/${repo}` ]; } const matchGithubIO = link.match(regexpGithubIO); if (matchGithubIO) { const repo = `${matchGithubIO[1]}/${matchGithubIO[2]}`; badges = [ `https://badgen.net/github/stars/${repo}`, `https://badgen.net/github/last-commit/${repo}` ]; } const matchGitlabCom = link.match(regexpGitlabCom); if (matchGitlabCom) { const repo = `${matchGitlabCom[1]}/${matchGitlabCom[2]}`; badges = [ `https://badgen.net/gitlab/stars/${repo}`, `https://badgen.net/gitlab/last-commit/${repo}` ]; } badges.forEach((badge) => { repoData.innerHTML += ``; }); } } catch (e) { console.error(e); } }); } loadRepoData(); document.querySelectorAll('table.plugins th').forEach((th) => { th.addEventListener('click', () => { sortTable(th); }); }); function sortTable(header) { const table = header.closest('table'); const tbody = table.tBodies[0]; const rows = Array.from(tbody.rows); // Column index to sort by const columnIndex = Array.from(header.parentNode.children).indexOf(header); // Skip the first row (headers) const fixedRow = rows.shift(); // Remove and keep the first row const dir = header.dataset.sortDir === 'asc' ? 'desc' : 'asc'; header.dataset.sortDir = dir; rows.sort((a, b) => { const aText = a.cells[columnIndex].textContent.trim(); const bText = b.cells[columnIndex].textContent.trim(); const aEmpty = aText === ''; const bEmpty = bText === ''; if (aEmpty && !bEmpty) { return dir === 'asc' ? 1 : -1; } if (!aEmpty && bEmpty) { return dir === 'asc' ? -1 : 1; } if (aEmpty && bEmpty) { return 0; } // Try to convert to numbers if possible const aVal = isNaN(aText) ? aText.toLowerCase() : parseFloat(aText); const bVal = isNaN(bText) ? bText.toLowerCase() : parseFloat(bText); if (aVal > bVal) { return dir === 'asc' ? 1 : -1; } if (aVal < bVal) { return dir === 'asc' ? -1 : 1; } return 0; }); // Clear tbody and re-add the fixed row and sorted rows tbody.innerHTML = ''; tbody.appendChild(fixedRow); rows.forEach(row => tbody.appendChild(row)); } </script>