Docs / Setup / React / MapLibre

MapLibre setup

How to use MapLibre on the Web through MapConductor — no key, the shortest path to a running map. maplibre-gl ships bundled with the package.

PACKAGE
react-for-maplibre
API KEY
None
CSS
Required
REACT NATIVE
Available
Same provider, other platformsAndroidiOS

Before you start

Node.js 18 or newer
React 18 or 19
STEP 01

Install

maplibre-gl comes bundled with the package — no separate install.

terminalnpm
npm install @mapconductor/js-sdk-core @mapconductor/js-sdk-react \
            @mapconductor/react-for-maplibre
STEP 02

Exclude it from Vite pre-bundling

Under Vite, add the provider to optimizeDeps.exclude. maplibre-gl v6 loads its worker by URL, and pre-bundling does not emit that worker file into .vite/deps, so the request fails.

vite.config.tsTypeScript · Vite
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
    optimizeDeps: {
        exclude: ["@mapconductor/react-for-maplibre", "@mapconductor/js-sdk-core"],
    },
    plugins: [react()],
});
STEP 03

Import the stylesheet

Import it once from your application entry point. Forget it and the map's layout and controls come out wrong.

main.tsxTypeScript
import '@mapconductor/react-for-maplibre/style.css';
STEP 04

Choose a style

MapLibre has no key, but you do choose where tiles come from. The default DemoTiles is for verification.

CAUTION
The OsmBright, MapTiler and OpenMapTiles styles are served from a Japan-focused public demo tile host (tile.openstreetmap.jp). Fine while developing — for production traffic and licensing compliance, point mapDesignType at your own hosted style JSON.

VERIFY

What you should see

A map centred on Tokyo with a single marker means you are done.

HelloMap.tsxTypeScript · React
import { useState } from 'react';
import { createGeoPoint, createMapCameraPosition, createMarkerState } from '@mapconductor/js-sdk-core';
import { Marker } from '@mapconductor/js-sdk-react';
import { MapLibreDesign, MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
import '@mapconductor/react-for-maplibre/style.css';

const TOKYO = createGeoPoint({ latitude: 35.6812, longitude: 139.7671 });

export function HelloMap() {
  const mapState = useMapLibreViewState({
    id: 'maplibre-map',
    mapDesignType: MapLibreDesign.DemoTiles,
    cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
  });
  const [markerState] = useState(() => createMarkerState({ id: 'tokyo', position: TOKYO }));

  return (
    <MapLibreMapView2D state={mapState} style={{ height: 480 }}>
      <Marker state={markerState} />
    </MapLibreMapView2D>
  );
}

State object

What useMapLibreViewState accepts. MapLibreMapView is the 3D view and MapLibreMapView2D the 2D one; they share the state.

signatureTypeScript
useMapLibreViewState({
  id?: string;
  mapDesignType?: MapLibreMapDesignType; // default MapLibreDesign.OsmBright
  cameraPosition?: MapCameraPosition;    // default MapCameraPosition.Default
})

// View props, on top of the shared MapViewBaseProps
{
  maxZoom?: number;
  minZoom?: number;
  projection?: 'mercator' | 'globe';   // a component prop, not part of state
  containerStyle?: React.CSSProperties;
  markerTilingOptions?: MarkerTilingOptions;
  onError?: (error: Error) => void;
}

Map designs

Each MapLibreDesign wraps a style JSON URL.

MapLibreDesign
Notes
DemoTiles
demotiles.maplibre.org — zero-config
OsmBright / OsmBrightEn / OsmBrightJa
OSM Bright, in default / English / Japanese label variants
MapTilerTonerEn / MapTilerTonerJa
The high-contrast Toner style
MapTilerBasicEn / MapTilerBasicJa
The pared-back Basic style
OpenMapTiles
The generic OpenMapTiles style

Troubleshooting

Changing the style blanks the map briefly

  • Changing mapDesignType re-initialises the map rather than calling setStyle — style swaps are not cheap. Avoid UI that toggles them constantly.

The map's layout or controls look broken

  • Check you imported style.css.

The map initialises twice in development

  • React StrictMode double-invokes effects. Every provider detects this and discards the aborted run, so you do not need to turn StrictMode off.

Next

Pass projection="globe" for a globe view. It is a component prop, not part of the state object.