vue3-maptiler-gl
| Install | |
|---|---|
npm install vue3-maptiler-gl |
|
| Latest Version: | 2.1.1 |
| Vue: | 3 |
| Last Updated: | Sep 10, 2026 |
| Links: | GitHub · npm |
Vue3 MapTiler SDK
The most comprehensive Vue 3 library for MapTiler SDK - Build interactive maps with 10 components and 38 composables
A powerful, feature-rich Vue 3 component library that provides an intuitive, reactive way to build interactive maps in your Vue applications using MapTiler SDK.
@maptiler/sdk is a peer dependency, re-exported from this package so your app and this one always share a single copy of the MapTiler runtime. npm and Bun would install it on their own; Yarn and pnpm would not, so the commands below name it explicitly.
Requirements: Vue ^3.0.0 and @maptiler/sdk ^4.1.0, both peer dependencies.
Using Nuxt? Install nuxt-maptiler-gl instead — it wraps this package with auto-imports, CSS injection, and the SSR configuration the MapTiler SDK needs.
API key: optional. Any http(s) style URL is passed through untouched, so a keyless style works with no MapTiler account — which is why the package default is one. You need a key only for maptiler:// styles, Cloud style ids such as streets-v2, or api.maptiler.com URLs; set it with useMapTilerConfig({ apiKey }). See Configuration.
✨ Features
- 🗺️ Interactive Maps - High-performance vector maps with WebGL rendering
- 🧩 10 Vue Components - MapTiler, GeoJsonSource, FillLayer, CircleLayer, LineLayer, SymbolLayer, Marker, Popup, Image, GeolocateControls
- 🔧 38 Composables - Complete map management, animations, events, and utilities
- 🎯 Full TypeScript Support - Comprehensive type definitions and interfaces
- ⚡ High Performance - Optimized rendering with automatic resource cleanup
- 📱 Mobile-Friendly - Touch controls and responsive design for all devices
- 🌐 Self-Contained - Bundled CSS and automatic dependency management
- 🔄 Reactive Data Binding - Seamless integration with Vue 3's reactivity system
📦 Installation
Using Bun (Recommended)
bun add vue3-maptiler-gl @maptiler/sdk
Using npm
npm install vue3-maptiler-gl @maptiler/sdk
Using Yarn
yarn add vue3-maptiler-gl @maptiler/sdk
Using pnpm
pnpm add vue3-maptiler-gl @maptiler/sdk
Styles are required and are not imported for you — importing CSS as a side effect of importing a component would defeat tree-shaking. Do this once, at your application entry. style-with-maptiler.css is the SDK's stylesheet plus this package's own rules, so one import covers both:
import 'vue3-maptiler-gl/dist/style-with-maptiler.css';
Apps that already load @maptiler/sdk/dist/maptiler-sdk.css should import vue3-maptiler-gl/dist/style.css alongside it instead, rather than shipping the SDK's CSS twice.
ESM only.
@maptiler/sdkships an ES module and nothing else — itsexportsmap offers a single"import"condition and no browser global — so this package ships no UMD build and cannot be loaded from a plain<script>tag. See Installation for a CDN setup that works.
🚀 Quick Start
<template>
<MapTiler :options="mapOptions" style="height: 500px" @load="onMapLoad">
<!-- GeoJSON Data Source -->
<GeoJsonSource :data="geoJsonData">
<FillLayer :style="fillStyle" />
<CircleLayer :style="circleStyle" />
</GeoJsonSource>
<!-- Interactive Marker -->
<Marker :lnglat="[0, 0]" :draggable="true">
<div class="marker">📍</div>
</Marker>
<!-- Popup -->
<Popup :lnglat="[0, 0]" :show="true">
<div class="popup-content">
<h3>Welcome to Vue3 MapTiler SDK!</h3>
<p>Interactive maps made easy with Vue 3</p>
</div>
</Popup>
<!-- Geolocation Control -->
<GeolocateControls position="top-right" />
</MapTiler>
</template>
<script setup>
import { ref } from 'vue';
import {
MapTiler,
GeoJsonSource,
FillLayer,
CircleLayer,
Marker,
Popup,
GeolocateControls,
} from 'vue3-maptiler-gl';
import 'vue3-maptiler-gl/dist/style-with-maptiler.css';
const mapOptions = ref({
style: 'https://demotiles.maplibre.org/style.json',
center: [0, 0],
zoom: 2,
// The SDK adds its own locate button by default; turn it off so
// <GeolocateControls> above does not render a second one.
geolocateControl: false,
});
const geoJsonData = ref({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: { type: 'Point', coordinates: [0, 0] },
properties: { name: 'Sample Point' },
},
],
});
const fillStyle = ref({
'fill-color': '#088',
'fill-opacity': 0.8,
});
const circleStyle = ref({
'circle-radius': 6,
'circle-color': '#007cbf',
});
function onMapLoad(event) {
// `@load` forwards the SDK's own event. The map is `event.target`; the
// `onMapLoad` prop is the one that receives the map directly.
console.log('Map loaded:', event.target);
}
</script>
<style>
.marker {
font-size: 24px;
cursor: pointer;
}
.popup-content {
padding: 10px;
max-width: 200px;
}
</style>
The SDK brings its own controls.
MapOptions.navigationControlandMapOptions.geolocateControlboth default totrue, where MapLibre adds none, so a bare<MapTiler>already shows zoom, compass and locate buttons. PassnavigationControl: false/geolocateControl: falsewhen you place your own.
An inline style object does not work in the constructor. The SDK's
styleoption accepts a URL string, a MapTiler Cloud style id or aReferenceMapStyle; a plainStyleSpecificationobject silently yields no map. Build the map first and callsetStyle()with the object instead. See Migration v1 → v2.
🧩 Components
All 10 components are reactive and register themselves with the map they are nested in:
| Component | Description |
|---|---|
| MapTiler | Main map container with comprehensive event handling |
| GeoJsonSource | Reactive data source for GeoJSON data with clustering support |
| FillLayer | Render filled polygons with customizable styling |
| CircleLayer | Display point data as circles with dynamic sizing |
| LineLayer | Render linear features like routes and boundaries |
| SymbolLayer | Display icons and text labels |
| Marker | HTML markers with drag support and custom content |
| Popup | Interactive popup windows with custom HTML |
| Image | Manage and load images for map styles |
| GeolocateControls | User location tracking with comprehensive events |
🔧 Composables
All 38 composables are exported from the package root, and every component in the table above is built out of them — reach for one when you want the behaviour without the component:
Map
useCreateMapTiler- Create and manage a map instance, with status and error stateuseMapTiler- Hold a map created elsewhere; pass it what<MapTiler>emits from@registeruseMapTilerConfig- Global MapTiler settings, includingapiKey, set once at app startupuseCreateMarker- Marker creation and lifecycleuseCreatePopup- Popup creation and lifecycleuseCreateImage- Load and manage style imagesuseLayer- Hold a layer created elsewhere, with reactive status and style setters
Layers
useCreateLayer- Generic layer creation for any layer typeuseCreateFillLayer- Fill layer for polygonsuseCreateCircleLayer- Circle layer for point datauseCreateLineLayer- Line layer for linear featuresuseCreateSymbolLayer- Symbol layer for icons and text
Sources
useCreateGeoJsonSource- GeoJSON source with reactive datauseGeoJsonSource- Hold a GeoJSON source created elsewhere, with error handling
Controls
useGeolocateControl- User location tracking control
Events
useMapEventListener- Map events, typed by event nameuseLayerEventListener- Layer-scoped eventsuseGeolocateEventListener- Geolocate control eventsuseMapReloadEvent- Re-run work after a style reload
Camera
usePanBy/usePanTo- Pan by an offset, or to a coordinateuseRotateTo/useSnapToNorth/useResetNorth/useResetNorthPitch- Bearing and pitchuseZoomIn/useZoomOut/useZoomTo- Zoom controluseFitBounds/useCameraForBounds- Fit the camera to a bounding boxuseFitScreenCoordinates- Fit the camera to two screen points
Animations and utilities
useFlyTo- Curved fly-to animationuseEaseTo- Eased camera transitionuseJumpTo- Instant camera moveuseLogger- Logging gated on adebugflag
Performance
useDebounce- Debounce a functionuseDebouncedRef- Immediate and debounced views of one valueuseDebouncedWatch- Debouncedwatch
Full signatures and return types: Composables API.
🎯 TypeScript Support
Vue3 MapTiler SDK includes comprehensive TypeScript support:
import { ref } from 'vue';
import {
MapTiler,
GeoJsonSource,
FillLayer,
type MapOptions,
type FillLayerStyle,
type GeoJSONSourceSpecification,
} from 'vue3-maptiler-gl';
const mapOptions = ref<Partial<MapOptions>>({
style: 'https://demotiles.maplibre.org/style.json',
center: [0, 0],
zoom: 2,
});
const fillStyle = ref<FillLayerStyle>({
'fill-color': '#088',
'fill-opacity': 0.8,
});
const geoJsonData = ref<GeoJSONSourceSpecification['data']>({
type: 'FeatureCollection',
features: [],
});
MapTiler SDK types come from the package root, because types cost nothing at runtime:
import type { Map, MapOptions, StyleSpecification } from 'vue3-maptiler-gl';
MapTiler SDK runtime classes live on the /maptiler subpath, so importing a component from the root does not pin the whole MapTiler runtime into your bundle:
import {
Map,
NavigationControl,
MapTilerMarker,
} from 'vue3-maptiler-gl/maptiler';
Marker and Popup collide with the Vue components of the same name, so they are re-exported as MapTilerMarker / MapTilerPopup — or reach them through the namespace:
import { MapTilerPopup, maptilersdk } from 'vue3-maptiler-gl/maptiler';
import { Marker } from 'vue3-maptiler-gl';
const popup = new MapTilerPopup();
const marker = new maptilersdk.Marker();
Marker in the example above is the Vue component; importing straight from @maptiler/sdk works too.
🌟 Advanced Example with Composables
<template>
<div ref="mapContainer" style="height: 500px" />
</template>
<script setup>
import { ref } from 'vue';
import {
useCreateMapTiler,
useFlyTo,
useMapEventListener,
useCreateGeoJsonSource,
} from 'vue3-maptiler-gl';
// The map initializes itself as soon as this ref resolves to an element.
const mapContainer = ref();
const mapStyle = ref('https://demotiles.maplibre.org/style.json');
// Create map with enhanced error handling
const { mapInstance, setCenter, setZoom } = useCreateMapTiler(
mapContainer,
mapStyle,
{
onLoad: (map) => console.log('Map loaded:', map),
onError: (error) => console.error('Map error:', error),
debug: true,
},
);
// Add smooth animations
const { flyTo } = useFlyTo({ map: mapInstance });
// Create reactive data source
const { setData } = useCreateGeoJsonSource({
map: mapInstance,
id: 'my-source',
data: { type: 'FeatureCollection', features: [] },
});
// Listen to map events
useMapEventListener({
map: mapInstance,
event: 'click',
on: (event) => {
flyTo({
center: event.lngLat,
zoom: 12,
duration: 2000,
});
},
});
</script>
📚 Documentation
- Getting Started - Learn the basics and see examples
- Installation Guide - Detailed setup instructions
- Configuration - API key, global config, per-map overrides
- Components API - Complete component documentation
- Composables API - Composables reference
- TypeScript Types - Type definitions
- SSR / Nuxt - Server-side rendering and the Nuxt module
- Migration v1 → v2 - Breaking changes and how to move
- Live Examples - Interactive demos
🛠️ Development
# Clone the repository
git clone https://github.com/danh121097/vue-maptiler-gl.git
cd vue-maptiler-gl
# Install dependencies
bun install
# Start development server
bun run dev
# Build the library
bun run build
# Run documentation
bun run docs:dev
🌟 Why Choose Vue3 MapTiler SDK?
- 🎯 Vue 3 Native - Built specifically for Vue 3 with Composition API support
- 🗺️ MapTiler SDK - MapLibre's WebGL rendering plus MapTiler Cloud styles and helpers
- 🧩 Component-Based - 10 Vue components for maps, layers, sources, markers, and controls
- 🔧 Powerful Composables - 38 composables for map management, animations, and utilities
- 📚 Comprehensive Documentation - Detailed guides, API references, and examples
- ⚡ High Performance - Optimized for performance with automatic resource cleanup
- 🌐 Open Source - MIT licensed with active community support
- 📱 Mobile Ready - Touch-friendly controls and responsive design
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Setup
The Development section above has the clone-and-run steps. Before opening a pull request:
bun run test
bun run type-check
bun run lint:check
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built on top of the MapTiler SDK (BSD-3-Clause), which wraps MapLibre GL JS and adds MapTiler Cloud styles, geocoding and helpers
- Ported from vue3-maplibre-gl, whose API this package mirrors
- Thanks to all contributors and users who make this project better
📞 Support
- 📖 Documentation - Comprehensive guides and API reference
- 🐛 Issues - Bug reports and feature requests
- 💬 Discussions - Community discussions and questions
- ⭐ GitHub - Star the project if you find it useful!
Made with ❤️ for the Vue.js community
Related Packages
Vue 3 components and composables for MapLibre GL JS - Build interactive maps wit...
A minimalist Vue component wrapping Mapbox GL or MapLibre GL dynamic maps!
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 2.1.1 | ^3.0.0 | ||
| 2.0.2 | ^3.0.0 | ||
| 2.0.1 | ^3.0.0 | ||
| 2.0.0 | ^3.0.0 | ||
| 1.0.1 | ^3.0.0 | MIT | |
| 1.0.0 | ^3.0.0 | MIT |