Add an editable dataset in Leaflet
Copy JavaScript and React examples for loading a published dataset revision as GeoJSON from the Mappinest Dataset API in Leaflet.
Overview
This guide shows how to fetch the latest published dataset revision as one GeoJSON FeatureCollection and render it in Leaflet. Use this path when the full dataset fits your application flow and you want to manage supported features in Dataset Studio.
Create a dataset from .geojson or .json in Datasets, or start drawing in Studio. The examples use the `mappinest.world-cities` sample. Copy the owner-scoped Dataset ID from the Datasets page when working with your own data.
Leaflet renders the FeatureCollection directly with L.geoJSON. The example uses the MapLibre bridge only for the Mappinest background StyleJSON.
API key scopes
The browser API key needs datasets:read. The examples also use the light map style as a background, so add maps:read when the key has explicit scopes. Add every development and production origin to the allowed-domain policy.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mappinest Dataset GeoJSON with Leaflet</title>
<link href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" rel="stylesheet" />
<link href="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.css" rel="stylesheet" />
<style>
body { margin: 0; }
#map { height: 100vh; width: 100vw; }
</style>
</head>
<body>
<div id="map"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/maplibre-gl@5/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.1.3/leaflet-maplibre-gl.js"></script>
<script>
const apiKey = 'YOUR_MAPPINEST_KEY';
const datasetId = 'mappinest.world-cities';
const map = L.map('map').setView([20, 0], 2);
L.maplibreGL({
style: `https://api.mappinest.com/v1/maps/light/style.json?key=${apiKey}`,
interactive: false
}).addTo(map);
async function loadDataset() {
const response = await fetch(
`https://api.mappinest.com/v1/datasets/${datasetId}.geojson?key=${encodeURIComponent(apiKey)}`
);
if (!response.ok) {
throw new Error('Dataset GeoJSON request failed.');
}
const layer = L.geoJSON(await response.json(), {
pointToLayer: (_feature, latlng) => L.circleMarker(latlng, {
radius: 6,
color: '#ffffff',
weight: 1.5,
fillColor: '#2563eb',
fillOpacity: 1
})
}).addTo(map);
if (layer.getBounds().isValid()) {
map.fitBounds(layer.getBounds(), { padding: [40, 40], maxZoom: 13 });
}
}
loadDataset();
</script>
</body>
</html>import { useEffect, useRef } from 'react';
import L from 'leaflet';
import '@maplibre/maplibre-gl-leaflet';
import 'leaflet/dist/leaflet.css';
import 'maplibre-gl/dist/maplibre-gl.css';
const apiKey = 'YOUR_MAPPINEST_KEY';
const datasetId = 'mappinest.world-cities';
export default function MappinestLeafletDatasetMap() {
const containerRef = useRef<HTMLDivElement | null>(null);
const mapRef = useRef<L.Map | null>(null);
useEffect(() => {
if (!containerRef.current || mapRef.current) return;
let cancelled = false;
const map = L.map(containerRef.current).setView([20, 0], 2);
mapRef.current = map;
(L as any).maplibreGL({
style: `https://api.mappinest.com/v1/maps/light/style.json?key=${apiKey}`,
interactive: false
}).addTo(map);
async function loadDataset() {
const response = await fetch(
`https://api.mappinest.com/v1/datasets/${datasetId}.geojson?key=${encodeURIComponent(apiKey)}`
);
if (!response.ok) throw new Error('Dataset GeoJSON request failed.');
const dataset = await response.json();
if (cancelled) return;
const layer = L.geoJSON(dataset, {
pointToLayer: (_feature, latlng) => L.circleMarker(latlng, {
radius: 6,
color: '#ffffff',
weight: 1.5,
fillColor: '#2563eb',
fillOpacity: 1
})
}).addTo(map);
if (layer.getBounds().isValid()) {
map.fitBounds(layer.getBounds(), { padding: [40, 40], maxZoom: 13 });
}
}
void loadDataset().catch((error) => {
if (!cancelled) console.error(error);
});
return () => {
cancelled = true;
map.remove();
mapRef.current = null;
};
}, []);
return <div ref={containerRef} style={{ height: 420, width: '100%' }} />;
}Dataset GeoJSON URL pattern
Create a browser API key in API Keys & Access, then replace YOUR_MAPPINEST_KEY. The examples use the `mappinest.world-cities` sample. Replace the Dataset ID when working with your own data.
Adjust the example center or let the map client fit the returned feature bounds when your dataset is in another location.
Refresh after publishing
Publishing in Studio or applying a server mutation creates a new immutable revision. Fetch the same endpoint URL again to receive the latest authorized revision. For explicit revalidation, store the response ETag and send it in If-None-Match. A 304 Not Modified response has no GeoJSON body, so keep the FeatureCollection already loaded by the application.
Common errors
What to read next
Last updated: September 10, 2026