react-map-gl mit MapLibre
react-map-gl verpackt MapLibre GL JS in React-Komponenten: die Karte, Marker, Popups, Controls, Quellen und Layer. Eine Kartenkomponente mit einer Stil-URL, einem Marker und 3D-Gelände, die Einrichtung, die MapLibre 6 mit Vite und Next.js braucht, und wohin der Schlüssel gehört. Getestet mit react-map-gl 8.1.3, MapLibre GL JS 6.13.0, React 19.3 und Vite 8.
npm install react-map-gl maplibre-gl
import Map from "react-map-gl/maplibre";
import "maplibre-gl/dist/maplibre-gl.css";
export default function MapView() {
return (
<Map
initialViewState={{ longitude: 8.54, latitude: 47.37, zoom: 12 }}
style={{ width: "100%", height: 480 }}
mapStyle="https://api.overpass.ch/v1/IHR_SCHLÜSSEL/maps/styles/light.json"
/>
);
}
Mit Vite ergänzen Sie die Zeilen mit setWorkerUrl unten, sonst bleibt die Karte leer.
Eine Karte mit Marker, Popup und 3D-Gelände
Diese Komponente lief in einem Build mit Vite. Sie zeigt den Stil Outdoor geneigt über dem Matterhorn, mit Gelände, einem Marker und seinem Popup:
import { useState } from "react";
import Map, { NavigationControl, Marker, Popup, Source } from "react-map-gl/maplibre";
import { setWorkerUrl } from "maplibre-gl";
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";
import "maplibre-gl/dist/maplibre-gl.css";
setWorkerUrl(workerUrl); // MapLibre 6 mit Vite: einmal, vor der ersten Karte
const KEY = import.meta.env.VITE_OVERPASS_KEY;
const MAPS = `https://api.overpass.ch/v1/${KEY}/maps`;
export default function MapView() {
const [open, setOpen] = useState(true);
return (
<Map
initialViewState={{ longitude: 7.6586, latitude: 45.9763, zoom: 12, pitch: 60, bearing: -100 }}
style={{ width: "100%", height: 480 }}
mapStyle={`${MAPS}/styles/outdoor.json?lang=de`}
maxPitch={85}
terrain={{ source: "terrain-3d", exaggeration: 1.2 }}
>
<Source id="terrain-3d" type="raster-dem" url={`${MAPS}/terrain.json`} />
<NavigationControl visualizePitch />
<Marker longitude={7.7491} latitude={46.0207} color="#d0312d" onClick={() => setOpen(true)} />
{open && (
<Popup longitude={7.7491} latitude={46.0207} anchor="bottom" offset={36} onClose={() => setOpen(false)}>
Zermatt
</Popup>
)}
</Map>
);
}
- Importieren Sie aus
react-map-gl/maplibre. Es lädtmaplibre-glselbst und funktioniert mit den ES-Modulen von MapLibre 6. Das Paket@vis.gl/react-maplibrehat dieselben Komponenten ohne den Teil für Mapbox. mapStylenimmt die Stil-URL. Ändern Sie sie, wechselt der Stil, zum Beispiel vonlightzudarkmit dem Design Ihrer App.terrainverweist mit ihrer ID auf eine Quelleraster-dem. Das KindSourcefügt diese Quelle hinzu. Für 3D ohne Code hängen Sieterrain=1an die Stil-URL; dieser Stil enthält schon eine Quelleterrain-3d.- Für eigene Daten verwenden Sie
<Source type="geojson" data={…}>mit einem Kind<Layer>.
Die Worker-URL
MapLibre liest Kacheln in einem Web Worker. Mit einem Bundler findet MapLibre 6 die Worker-Datei nicht selbst: Die Karte bleibt leer, und die Konsole zeigt «Worker failed to load. Check that the worker URL is correct.» Das haben wir gesehen, bevor wir den Aufruf ergänzt haben.
- Vite (getestet):
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url"undsetWorkerUrl(workerUrl), wie oben. - Next.js 15 und neuer, mit Turbopack oder webpack: Die Dokumentation von MapLibre nennt
setWorkerUrl(new URL("maplibre-gl/dist/maplibre-gl-worker.mjs", import.meta.url).toString())in einer Datei, die mit"use client"beginnt. Für Next.js 14 sagt sie, die Worker-Datei nachpublic/zu kopieren und diesen Pfad zu übergeben.
Die Karte braucht den Browser; setzen Sie sie in Next.js also in eine Client-Komponente. Mit Server-Rendering wird der Container auf dem Server gerendert, und die Karte startet im Browser.
Der Schlüssel
Die Stil-URL enthält Ihren Schlüssel, und der Browser sieht ihn. Legen Sie ihn in eine Umgebungsvariable, damit er nicht in Ihrem Repository landet:
# .env.local (Vite: Präfix VITE_; Next.js: Präfix NEXT_PUBLIC_) VITE_OVERPASS_KEY=IHR_SCHLÜSSEL
Erstellen Sie dann in Ihrem Dashboard einen Schlüssel vom Typ «Nur Karten», mit Ihrer Website und localhost:5173 (Vite) oder localhost:3000 (Next.js) als erlaubten Referern. Ein solcher Schlüssel funktioniert nur für Kacheln und Stile, und andere Websites werden abgewiesen.
Kacheln
react-map-gl ändert nichts an der Zählung: Jede Vektor-, Gelände- oder Höhenlinienkachel, die MapLibre lädt, zählt als eine Kartenkachel, und Stile und Schriften sind kostenlos. In 3D lädt die Karte Kacheln bis zum Horizont; die Anleitung zu 3D-Gelände hat Zahlen. Jedes Konto enthält 100'000 Kacheln im Monat.