All integrations OpenLayers React WordPress API docs

ExpressMaps in React

Two ways: a small component around MapLibre GL JS, or react-map-gl if you prefer a declarative API. Both produce the map below.

Option 1: a MapLibre component

Install the library, then create the map in an effect and clean it up on unmount. No provider, no context, no token.

npm install maplibre-gl
import { useEffect, useRef } from "react";
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";

const STYLE = "https://tiles.expressmaps.com/styles/standard.json?key=" + process.env.REACT_APP_EXPRESSMAPS_KEY;

export default function ExpressMap({ lng = -0.1276, lat = 51.5072, zoom = 12, marker = true }) {
  const container = useRef(null);

  useEffect(() => {
    const map = new maplibregl.Map({ container: container.current, style: STYLE, center: [lng, lat], zoom });
    map.addControl(new maplibregl.NavigationControl(), "top-right");
    if (marker) new maplibregl.Marker().setLngLat([lng, lat]).addTo(map);
    return () => map.remove();
  }, [lng, lat, zoom, marker]);

  return <div ref={container} style={{ width: "100%", height: 400 }} />;
}

Use it anywhere: <ExpressMap lng={-0.1276} lat={51.5072} zoom={12} />. The key is public by design; restrict it to your domain in the console.

Option 2: react-map-gl

react-map-gl wraps MapLibre with React components for markers, popups and controls. Import from the /maplibre entry point.

npm install react-map-gl maplibre-gl
import Map, { Marker, Popup, NavigationControl } from "react-map-gl/maplibre";
import "maplibre-gl/dist/maplibre-gl.css";
import { useState } from "react";

export default function OfficeMap() {
  const [open, setOpen] = useState(false);
  return (
    <Map
      initialViewState={{ longitude: -0.1276, latitude: 51.5072, zoom: 12 }}
      style={{ width: "100%", height: 400 }}
      mapStyle={"https://tiles.expressmaps.com/styles/standard.json?key=" + import.meta.env.VITE_EXPRESSMAPS_KEY}
    >
      <NavigationControl position="top-right" />
      <Marker longitude={-0.1276} latitude={51.5072} onClick={() => setOpen(true)} />
      {open && (
        <Popup longitude={-0.1276} latitude={51.5072} onClose={() => setOpen(false)}>
          Our office
        </Popup>
      )}
    </Map>
  );
}

Next.js

MapLibre needs the browser, so load the component client-side only:

import dynamic from "next/dynamic";
const ExpressMap = dynamic(() => import("../components/ExpressMap"), { ssr: false });

Expose the key as NEXT_PUBLIC_EXPRESSMAPS_KEY. Because it is domain-restricted it is safe in client bundles.

Switching styles at runtime

Call map.setStyle(url) with another of the ten styles, or pass a new mapStyle prop. The tileset is shared, so switching is instant.

Get a free API key Read the docs