Nuxt-Mapbox
Elegant Mapbox integration with Nuxt
Now With Persistent Maps!


Features
- 🏗 Easily add Mapbox to your Nuxt app with Vue components
- 🌎 useMapbox Composable for easy access
- 👷 defineMapboxMarker & defineMapboxPopup for making custom components
- 🎛️ defineMapboxControl for creating your own controls
- 📖 Persistent map instances across routes
Quick Setup
- Add
nuxt-mapbox & mapbox-gl dependencies to your project
pnpm add -D nuxt-mapbox mapbox-gl
yarn add --dev nuxt-mapbox mapbox-gl
npm install --save-dev nuxt-mapbox mapbox-gl
- Add
nuxt-mapbox to the modules section of nuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-mapbox'
]
})
- Add your Mapbox API key to the
mapbox section of nuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-mapbox'
],
mapbox: {
accessToken: '{API_KEY}'
}
})
Usage
View the Mapbox GL JS Docs for reference.
Map instances are created with components. You can provide all the options through component props
Example:
<MapboxMap
map-id="{ID}"
style="position: absolute; top: 0; bottom: 0; left: 250px; width: 500px;"
:options="{
style: 'mapbox://styles/mapbox/light-v11', // style URL
center: [-68.137343, 45.137451], // starting position
zoom: 5 // starting zoom
}"
>
You can add Layers & Controls by nesting their components inside the Map
Examples:
<MapboxMap>
<MapboxSource
source-id="geojson"
:source="{
type: 'geojson',
data: '/test.geojson'
}"
/>
<MapboxLayer
source-id="geojson"
:layer="{
source: 'geojson',
id: 'geojson-layer',
type: 'fill'
}"
/>
</MapboxMap>
<MapboxMap>
<MapboxLayer
source-id="{ID}"
:source="{
type: 'geojson',
data: '/test.geojson'
}"
:layer="{
source: '{ID}',
id: 'geojson-layer',
type: 'fill'
}"
/>
<MapboxFullscreenControl />
</MapboxMap>
Persistent Map Instances
For map instances to be persistent across routes, keepalive must be set to true in nuxt.config.ts.
This is done by default, but you can disable it by setting keepalive to false
Events
All Map events are accessible directly through the component (With full Typescript support!)
View a list of events in the Mapbox Docs
Example:
<MapboxMap
...
@load="exampleFunction"
@click="exampleFunction"
@resize="exampleFunction"
>
You can access events directly on layers as well
Example:
<MapboxLayer
...
@click="exampleFunction"
>
You can have a popup linked to a marker by simply nesting the popup component inside the marker.
Example:
<MapboxDefaultMarker
marker-id="marker1"
:options="{}"
:lnglat="[110, 5]"
>
<MapboxDefaultPopup
popup-id="popup1"
:lnglat="[100, 0]"
:options="{
closeOnClick: false
}"
>
<h1 class="test">
Hello World!
</h1>
</MapboxDefaultPopup>
</MapboxDefaultMarker>
Map Instance
You can access the map instance with the useMapbox composable. You must provide the map id.
The map instance will not be available until the page is fully loaded, so you must access it through a callback
useMapbox(mapId, (map) => {
})
You can access the map instance ref directly with useMapboxInstance
NOTE: The map instance will be null until is initialized so you cannot access it directly on setup. Use a watcher as shown or useMapbox instead:
const map = useMapboxInstance(mapId)
watch(map, () => {
if (map.value)
})
Custom Components
While it is recommended to use the default components, making your own is easy with the built in composables!
You can use defineMapboxPopup & defineMapboxMarker for custom marker & popup components
By passing a template ref you can put custom html directly into your component
Examples:
const popup = defineMapboxPopup(popupId, options, templateRef)
popup?.setLngLat(lnglat)
NOTE: Because of the way markers are implemented in Mapbox, if passing a template ref to defineMapboxPopup you have to define properties in a callback like so:
const markerRef = defineMapboxMarker(markerId, options, templateRef, (marker) => {
marker.setLngLat([110, 6])
})
Custom Controls
You can make your own control with the defineMapboxControl composable.
Example:
useMapbox(mapID, (map) => {
if (htmlRef.value) {
const control = defineMapboxControl((_map) => {
return htmlRef.value as HTMLElement;
}, (map) => {})
map.addControl(control);
}
})
Custom Map Component
If you would like to make your own map component, you can use defineMapboxInstance
Example:
const map = defineMapboxInstance(MAP_DIV_ID, options);
Development
npm install
npm run dev:prepare
npm run dev
npm run dev:build
npm run lint
npm run test
npm run test:watch
npm run release