MapLibre GL JS
MapLibre GL JS renders the full vector outdoor style with hardware-accelerated WebGL — interactive, smooth, and supports 3D terrain.
Full working example: github.com/mapriot/map-examples/MaplibreGLJS — clone and run with
npm install && npm run dev.
Quick start (CDN)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>MapRiot — MapLibre GL JS</title>
<link href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<style>
body { margin: 0; }
#map { width: 100%; height: 100dvh; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const MAPRIOT_APIKEY = 'YOUR_API_KEY';
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.mapriot.com/styles/outdoor.json',
center: [14.42, 50.08],
zoom: 13,
attributionControl: {
customAttribution:
'<a href="https://mapriot.com/copyright" target="_blank">© MapRiot.com</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>'
},
transformRequest: (url) => {
if (url.startsWith('https://api.mapriot.com') && !url.includes('apiKey')) {
return {
url: url + (url.includes('?') ? '&' : '?') + 'apiKey=' + MAPRIOT_APIKEY,
};
}
return { url };
},
});
map.addControl(new maplibregl.NavigationControl());
map.addControl(new maplibregl.ScaleControl());
</script>
</body>
</html>Authentication with transformRequest
The style JSON references tile, font, and sprite URLs on api.mapriot.com. Each of these subrequests also requires your API key. The transformRequest callback appends it automatically to every request:
transformRequest: (url) => {
if (url.startsWith('https://api.mapriot.com') && !url.includes('apiKey')) {
return {
url: url + (url.includes('?') ? '&' : '?') + 'apiKey=' + MAPRIOT_APIKEY,
};
}
return { url };
},Without transformRequest, only the initial style JSON loads — tile and font requests will fail.
With 3D terrain
map.on('load', () => {
map.addSource('terrain', {
type: 'raster-dem',
url: 'https://api.mapriot.com/hillshading',
});
map.setTerrain({ source: 'terrain', exaggeration: 1.5 });
map.addControl(new maplibregl.TerrainControl({
source: 'terrain',
exaggeration: 1.5,
}));
map.setSky({
'sky-color': '#93bcdb',
'sky-horizon-blend': 0.5,
'horizon-color': '#d8dde1',
'horizon-fog-blend': 0.5,
'fog-color': '#b8bcb7',
'fog-ground-blend': 0.5,
});
});The hillshading source is already defined inside the outdoor style for 2D hillshading. The terrain source above is an additional reference to the same DEM data, used specifically for 3D terrain extrusion.
npm / bundler
npm install maplibre-glimport maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
const MAPRIOT_APIKEY = 'YOUR_API_KEY';
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.mapriot.com/styles/outdoor.json',
center: [14.42, 50.08],
zoom: 13,
transformRequest: (url) => {
if (url.startsWith('https://api.mapriot.com') && !url.includes('apiKey')) {
return {
url: url + (url.includes('?') ? '&' : '?') + 'apiKey=' + MAPRIOT_APIKEY,
};
}
return { url };
},
});Attribution
All maps must display MapRiot and OpenStreetMap attribution. The attributionControl option handles this:
attributionControl: {
customAttribution:
'<a href="https://mapriot.com/copyright">© MapRiot.com</a> ' +
'<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>'
},On mobile, MapLibre automatically collapses the attribution behind a button.