React
<ml-map> is a custom element, so React renders it like any other tag. There
is no wrapper component to install: register the element, import MapLibre’s
CSS, and reference the typings once.
npm install @maplibre-yaml/core maplibre-glimport { setWorkerUrl } from "maplibre-gl";import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";import "maplibre-gl/dist/maplibre-gl.css";import "@maplibre-yaml/core/register";
// maplibre-gl 6 is ESM-only and cannot find its worker inside a bundle;// point it there before the first map renders (v4/v5: drop these lines).setWorkerUrl(workerUrl);/// <reference types="@maplibre-yaml/core/react" />The typings entry is types only (an empty module at runtime). It teaches
React’s JSX about <ml-map>: src, config, a ref typed as MLMap
(mapReady(), getMap()), slot children, and on React 19 the
onml-map:* event props, each typed with its event’s detail.
A working app to copy from
Section titled “A working app to copy from”examples/react
is a Vite + React + TypeScript app that does everything on this page: a map
from a YAML file with its params panel, one from a config object, events
reaching React state, mapReady() through a ref, React-rendered controls in a
map corner, mount and unmount under StrictMode, and the React 19 props. CI
builds it against React 18 and React 19, type-checks it against both
@types/react majors, and drives every build in a browser. The snippets in
Web Components → React are files from
that app, checked by a test, so they cannot drift from what CI runs.
React 18 or 19
Section titled “React 18 or 19”| React 19 | React 18 | |
|---|---|---|
config | the object (keep it stable) or a JSON string | a JSON string only: config={JSON.stringify(doc)} |
ml-map:* events | onml-map:load={…} props, or a ref + addEventListener | a ref + addEventListener |
| typings | object config and typed event props allowed | an object config is a type error |
A JSON string plus a ref-based listener works on both majors, which is what most of the example uses. An equal config never rebuilds the map, so re-rendering a parent is free; a changed one rebuilds it.
Next.js
Section titled “Next.js”The element class extends HTMLElement, which does not exist during server
rendering, so register it from an effect in a "use client" component rather
than with a top-level import. The server sends a plain <ml-map> tag, which
upgrades once the import resolves. The snippet is in
Web Components → Next.js.