Vue 3 components for MapLibre GL - Build beautiful, reactive map applications
- πΊοΈ Full MapLibre GL Support - Complete wrapper around MapLibre GL JS
- π₯ Vue 3 Composition API - Built with modern Vue 3 patterns
- π¦ TypeScript First - Fully typed with excellent IDE support
- π¨ Reactive Components - Reactive and composable map components
- π Nuxt 4 Ready - Seamlessly works with Nuxt 4 and SSR
- π― PMTiles Built-in - Native support for PMTiles protocol
# pnpm
pnpm add @geoql/v-maplibre maplibre-gl
# npm
npm install @geoql/v-maplibre maplibre-gl
# yarn
yarn add @geoql/v-maplibre maplibre-gl# deno
deno add @geoql/v-maplibre
# npm (using JSR)
npx jsr add @geoql/v-maplibre
# yarn
yarn dlx jsr add @geoql/v-maplibre
# pnpm
pnpm dlx jsr add @geoql/v-maplibre<script setup lang="ts">
import { VMap, VMarker } from '@geoql/v-maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';
import '@geoql/v-maplibre/dist/v-maplibre.css';
const mapOptions = {
style: 'https://demotiles.maplibre.org/style.json',
center: [-74.5, 40],
zoom: 9,
};
</script>
<template>
<VMap :options="mapOptions" style="height: 500px">
<VMarker :lng-lat="[-74.5, 40]"></VMarker>
</VMap>
</template>VMap- Main map componentVMarker- Interactive markersVPopup- Popups and tooltips
VLayerMaplibreGeojson- GeoJSON layersVLayerMaplibreVector- Vector tile layersVLayerMaplibreRaster- Raster tile layersVLayerMaplibreImage- Image layersVLayerMaplibreVideo- Video layersVLayerMaplibreCanvas- Canvas layersVLayerMaplibreCluster- Clustered point layersVLayerMaplibrePmtile- PMTiles layers
VControlNavigation- Navigation controls (zoom, rotate)VControlScale- Scale indicatorVControlGeolocate- Geolocation controlVControlFullscreen- Fullscreen toggleVControlAttribution- Attribution control
For Nuxt applications, wrap the map component with ClientOnly:
<script setup lang="ts">
import { VMap } from '@geoql/v-maplibre';
const mapOptions = {
style: 'https://demotiles.maplibre.org/style.json',
center: [-74.5, 40],
zoom: 9,
};
</script>
<template>
<ClientOnly>
<VMap :options="mapOptions" style="height: 500px"></VMap>
</ClientOnly>
</template>Add styles to your nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
css: [
'maplibre-gl/dist/maplibre-gl.css',
'@geoql/v-maplibre/dist/v-maplibre.css',
],
});Or create a Nuxt plugin to import styles:
// plugins/maplibre.client.ts
import 'maplibre-gl/dist/maplibre-gl.css';
import '@geoql/v-maplibre/dist/v-maplibre.css';
export default defineNuxtPlugin(() => {
// Plugin loaded
});<script setup lang="ts">
import { VMap, VLayerMaplibreGeojson } from '@geoql/v-maplibre';
import type { GeoJSONSourceSpecification } from 'maplibre-gl';
const geojsonSource: GeoJSONSourceSpecification = {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-74.5, 40],
},
properties: { name: 'Example Point' },
},
],
},
};
const layerOptions = {
id: 'points',
type: 'circle' as const,
paint: {
'circle-radius': 8,
'circle-color': '#007cbf',
},
};
</script>
<template>
<VMap :options="mapOptions" style="height: 500px">
<VLayerMaplibreGeojson
:source="geojsonSource"
:layer="layerOptions"
></VLayerMaplibreGeojson>
</VMap>
</template><script setup lang="ts">
import { VMap, VLayerMaplibrePmtile } from '@geoql/v-maplibre';
const pmtilesUrl = 'https://example.com/tiles.pmtiles';
const layerOptions = {
id: 'pmtiles-layer',
type: 'fill' as const,
paint: {
'fill-color': '#088',
'fill-opacity': 0.5,
},
};
</script>
<template>
<VMap :options="mapOptions" support-pmtiles style="height: 500px">
<VLayerMaplibrePmtile
:url="pmtilesUrl"
:layer="layerOptions"
></VLayerMaplibrePmtile>
</VMap>
</template>Visit our documentation site for:
- Complete API reference
- Detailed component guides
- Interactive examples
- Migration guides
All components are fully typed. Import types from maplibre-gl:
import type { MapOptions, LngLatLike, GeoJSONSource } from 'maplibre-gl';# Install dependencies
pnpm install
# Build the library
pnpm build
# Run documentation
pnpm docs:dev
# Build documentation
pnpm docs:buildMIT License - see LICENSE for details
Built with:
Contributions are welcome! Please feel free to submit a Pull Request.
Made with β€οΈ by GeoQL