MapboxMarker

Gitlab
A Vue component for adding markers to a Mapbox map with customizable rendering and behavior.
Added since: v0.1.0
Last changed:

Overview

MapboxMarker is a Vue component that provides a convenient way to add markers to a Mapbox map. It supports custom rendering through slots, dynamic element types, and automatic positioning based on GeoJSON features.

Key features:

  • Customizable marker rendering through slots
  • Dynamic element type (div, button, or NuxtLink)
  • Automatic positioning based on GeoJSON features
  • Type-safe integration with Mapbox GL JS
  • Context-based marker management

Usage

The component can be used to add markers to your map with custom content and behavior.

MapComponent.vue
<script setup lang="ts">
import type { Feature, Point } from 'geojson';

const markerFeature: Feature<Point> = {
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [-74.5, 40]
  },
  properties: {}
};
</script>

<template>
  <MapboxMarker
    id="my-marker"
    :feature="markerFeature"
    as="button"
    @click="handleMarkerClick"
  >
    <div class="custom-marker">
      <span>πŸ“</span>
    </div>
  </MapboxMarker>
</template>

API Reference

Props

PropDefaultType
id*
string
Unique identifier for the marker
options
{anchor: 'center'}
MarkerOptions
Mapbox marker options
feature
Feature<Point, any>
GeoJSON feature containing marker coordinates
as
string
HTML element type to render (div, button, etc.)
to
string
If provided, renders as NuxtLink with this destination

Slots

SlotPayload
default
undefined
Content to render inside the marker element

Exposed

ExposedType
marker
Marker
The marker instance

Context

The component provides a context that can be injected by child components to access the marker instance.

export type MapboxMarkerContext = {
  marker: Ref<Marker | null>;
};

export const [injectMapboxMarkerContext, provideMapboxMarkerContext]
  = createContext<MapboxMarkerContext>("MapboxMarker");

Example

<script setup lang="ts">
import type { Feature, Point } from 'geojson';

const markerFeature: Feature<Point> = {
  type: 'Feature',
  geometry: {
    type: 'Point',
    coordinates: [-74.5, 40]
  },
  properties: {
    title: 'New York'
  }
};
</script>

<template>
  <MapboxMarker
    id="custom-marker"
    :feature="markerFeature"
    :options="{ anchor: 'bottom' }"
    as="button"
    @click="handleClick"
  >
    <div class="marker-content">
      <h3>{{ markerFeature.properties.title }}</h3>
      <p>Click to view details</p>
    </div>
  </MapboxMarker>
</template>

<style scoped>
.marker-content {
  background: white;
  padding: 8px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
</style>

Best Practices

  1. Use the as prop to specify the appropriate element type based on your needs:
    • Use button for interactive markers
    • Use div for static markers
    • Use to prop for navigation markers
  2. Consider using the context when child components need to interact with the marker
  3. Handle marker cleanup in parent components when necessary

Changelog

v0.2.2

on

#56fc08c0

-

fix: resolved marker position flash on rendering

#93b26e58

-

improvement: updated src structure to match latest internal conventions

v0.1.1

on

#d40a96ab

-

chore: working module/ release pipeline