Add a WMS Source in MapLibre GL JS
WMS is a standard protocol for serving georeferenced map images from a remote server, commonly used by government and scientific data providers. In MapLibre GL JS, you connect a WMS endpoint as a raster tile source by constructing the required GetMap request URL template. Use this to overlay cadastral data, environmental monitoring layers, or any WMS-compatible spatial dataset on your map.
const API_KEY = 'YOUR_API_KEY';
const map = new maplibregl.Map({
container: 'map',
style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
center: [13.0, 47.5],
zoom: 6,
attributionControl: { compact: false }
});
map.addControl(new maplibregl.NavigationControl(), 'top-right');
map.on('load', () => {
map.addSource('wms-source', {
type: 'raster',
tiles: [
'https://ows.terrestris.de/osm/service?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=OSM-WMS&WIDTH=256&HEIGHT=256&SRS=EPSG%3A3857&STYLES=&BBOX={bbox-epsg-3857}'
],
tileSize: 256
});
map.addLayer({
id: 'wms-layer',
type: 'raster',
source: 'wms-source',
paint: { 'raster-opacity': 0.6 }
});
});
import { LogoControl } from "https://cdn.jsdelivr.net/npm/@maptoolkit/maplibre-logo-control@1.1.2/dist/maplibre-logo-control.js";
map.addControl(new LogoControl({ variant: "com" }));<!DOCTYPE html>
<html lang="en">
<head>
<title>Add a WMS Source - MapLibre GL JS</title>
<meta property="og:description" content="Add a WMS (Web Map Service) raster source to the map." />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/maplibre-gl@5.6.1/dist/maplibre-gl.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maplibre-gl@5.6.1/dist/maplibre-gl.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@maptoolkit/maplibre-logo-control@1.1.2/dist/maplibre-logo-control.css" />
<style>
html, body { width: 100%; height: 100%; margin: 0; padding: 0; }
#map { width: 100%; height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
const API_KEY = 'YOUR_API_KEY';
const map = new maplibregl.Map({
container: 'map',
style: `https://styles.maptoolkit.net/maptoolkit/maptoolkit.summer.json?api_key=${API_KEY}`,
center: [13.0, 47.5],
zoom: 6,
attributionControl: { compact: false }
});
map.addControl(new maplibregl.NavigationControl(), 'top-right');
map.on('load', () => {
map.addSource('wms-source', {
type: 'raster',
tiles: [
'https://ows.terrestris.de/osm/service?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=OSM-WMS&WIDTH=256&HEIGHT=256&SRS=EPSG%3A3857&STYLES=&BBOX={bbox-epsg-3857}'
],
tileSize: 256
});
map.addLayer({
id: 'wms-layer',
type: 'raster',
source: 'wms-source',
paint: { 'raster-opacity': 0.6 }
});
});
</script>
<script type="module">
import { LogoControl } from "https://cdn.jsdelivr.net/npm/@maptoolkit/maplibre-logo-control@1.1.2/dist/maplibre-logo-control.js";
map.addControl(new LogoControl({ variant: "com" }));
</script>
</body>
</html>Use the prompt below with any LLM to get the same result. Make sure the Maptoolkit MCP server is connected first — check out AI Integration & MCP to get started.
https://ows.terrestris.de/osm/service (OSM-WMS layer).How it works
WMS predates XYZ tiling, so a WMS server takes a bounding box and returns one image for it.
MapLibre GL JS bridges the two: a raster source whose tile template contains the
{bbox-epsg-3857} placeholder, which the renderer replaces per tile with that tile’s extent.
The parameters in the URL are the WMS contract rather than anything Maptoolkit defines.
SRS=EPSG:3857 has to be Web Mercator to line up with the map, WIDTH and HEIGHT must
match tileSize, and TRANSPARENT=true is what lets the basemap show through. Get the
projection wrong and the imagery lands in the wrong place rather than failing.
Some servers expect CRS instead of SRS, which is a WMS version difference: 1.3.0 uses
CRS, 1.1.1 uses SRS.
A WMS server renders on demand, so it is usually slower than a tiled service and worth caching if traffic is high.
Next steps
WMS servers usually publish many layers, and the LAYERS parameter is what selects them, so
the next step is often a control letting users choose between them
rather than hard-coding one.
Because these services are slower than a tiled raster source, opacity and a toggle matter more here than usual: an overlay people can fade or turn off is much more usable than one that is always on and always the slowest thing on the page.