MapboxMap JS
The MapboxMap component and its family let you build Mapbox GL maps declaratively, straight from your HTML, with js-toolkit. A MapboxMap element owns the underlying Mapbox Map instance, and every other component (markers, popups, controls, sources, layers, images, clusters) is authored as a child element that registers itself against that map once it is loaded.
These components are published in the standalone @studiometa/ui-mapbox package and replace the @studiometa/vue-mapbox-gl library. If you are coming from the Vue library, read the migration guide.
Table of content
Installation
Install the package alongside its mapbox-gl peer dependency. The @mapbox/mapbox-gl-geocoder package is only required if you use the MapboxGeocoder component.
npm install @studiometa/ui-mapbox mapbox-gl
# Optional, only for the geocoder control
npm install @mapbox/mapbox-gl-geocoderThe Mapbox GL stylesheet is required for the map, its controls and popups to render correctly. Add it to your page, either as a <link> tag pointing to the CDN or by importing it from the package with your bundler.
<link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/v3.13.0/mapbox-gl.css" />/* or, when using a bundler */
@import 'mapbox-gl/dist/mapbox-gl.css';You will also need a Mapbox access token. Pass it to the MapboxMap component through the access-token option.
Usage
Register each component your page uses: a bare map with just a container needs only MapboxMap, and each marker, popup, control, source, layer, image or cluster you declare must be registered too. Registration order does not matter, because a child registered before its MapboxMap still wires up once the map connects.
Author the map with a root MapboxMap element holding a container ref, and give it a size through CSS.
import { registerComponent } from '@studiometa/js-toolkit';
import { MapboxMap } from '@studiometa/ui-mapbox';
registerComponent(MapboxMap);<div
data-component="MapboxMap"
data-option-access-token="<YOUR_MAPBOX_ACCESS_TOKEN>"
data-option-zoom="10"
data-option-center="[2.35, 48.86]"
class="h-96 w-full">
<div data-ref="container" class="h-full w-full"></div>
</div>@import 'mapbox-gl/dist/mapbox-gl.css';mapbox-gl is a heavy dependency (~230 kB gzipped, more with the geocoder), so the recommended default is to register each component lazily — see Lazy loading below.
Lazy loading
Keep mapbox-gl out of your main bundle by registering the family as a manifest rather than as classes. A manifest entry is a lazy importer plus a mount strategy, so the dynamic import is deferred until an element that needs it is about to mount — mapbox-gl lands in its own chunk, loaded only when a map is actually on the page.
The package ships its own manifest, which is the shortest way to get all of it:
import { registerManifest } from '@studiometa/js-toolkit';
import { manifest } from '@studiometa/ui-mapbox/manifest';
registerManifest(manifest);Every component is also available at its own subpath (@studiometa/ui-mapbox/<Component>), whose default export is the component class, so a hand-written manifest can carry only the components you use. Each component is registered independently, so list every one you declare: deferring MapboxMap pulls in mapbox-gl, but a marker or a cluster is its own module and needs its own entry.
import { registerManifest } from '@studiometa/js-toolkit';
registerManifest({
MapboxMap: {
mountStrategy: 'visible',
load: () => import('@studiometa/ui-mapbox/MapboxMap'),
},
MapboxMarker: {
mountStrategy: 'visible',
load: () => import('@studiometa/ui-mapbox/MapboxMarker'),
},
MapboxPopup: {
mountStrategy: 'visible',
load: () => import('@studiometa/ui-mapbox/MapboxPopup'),
},
});Reach for a different strategy when it fits better — idle, interaction, media:<query> — and override any of them per element with data-mount. The Autoloading guide lists all six.