MapLibre GL JS manipule directement le DOM et WebGL — il n'a rien à faire côté serveur. Dans une app Next.js (App Router), ça veut dire un composant client, initialisé après le montage, avec un nettoyage propre au démontage. Ce guide couvre les pièges qui reviennent le plus souvent.
# npm, pnpm ou yarn selon ton projet
npm install maplibre-glDeux points non négociables : la directive "use client" en tête de fichier (MapLibre a besoin de window), et le CSS de la librairie importé quelque part — sans lui, les contrôles et le rendu sont cassés.
// app/components/Map.js "use client"; import { useEffect, useRef } from "react"; import maplibregl from "maplibre-gl"; import "maplibre-gl/dist/maplibre-gl.css"; export default function Map() { const containerRef = useRef(null); const mapRef = useRef(null); useEffect(() => { // Strict Mode monte/démonte les effets deux fois en dev — // cette garde évite d'initialiser deux cartes. if (mapRef.current) return; mapRef.current = new maplibregl.Map({ container: containerRef.current, style: "https://tiles.tilecatcdn.com/styles/default.json?key=YOUR_KEY", center: [2.3522, 48.8566], zoom: 11 ); return () => { mapRef.current?.remove(); mapRef.current = null; }; }, []); return <div ref={containerRef} style={{ height: "100%" }} />; }
MapLibre remplit la taille de son élément parent — s'il fait 0px de haut (ce qui arrive par défaut avec un div vide sans hauteur explicite), la carte reste invisible sans erreur console. Donne toujours une hauteur explicite au parent :
<div style={{ height: "500px" }}>
<Map />
</div>En développement, React 18+ monte, démonte puis remonte chaque composant pour détecter les effets de bord mal nettoyés. Sans la garde if (mapRef.current) return montrée plus haut, ça initialise deux instances de carte sur le même conteneur — symptôme classique : contrôles dupliqués, comportement erratique au zoom. Ce n'est pas un bug de MapLibre, c'est Strict Mode qui fait son travail ; le fix est côté composant.
new maplibregl.Marker() .setLngLat([2.3522, 48.8566]) .addTo(mapRef.current);
"use client" obligatoire, MapLibre ne tourne pas côté serveur.Pour la liste complète des endpoints (styles, tuiles, sprites, polices) et les quotas par plan, voir la documentation API.