Map

The simplest way to add an interactive map to your application.

Basic Usage

The Map component handles MapLibre GL setup, theming, and provides context for child components.

<template>
  <div class="h-[420px] w-full">
    <ClientOnly>
      <Map :center="[-74.006, 40.7128]" :zoom="12" />
    </ClientOnly>
  </div>
</template>

Controlled Mode

Use v-model:viewport (or the :viewport prop with @update:viewport) to control the viewport externally. Useful when you need to sync the map state with your application or react to viewport changes.

Center -74.006, 40.713

Zoom 11.00

<script setup lang="ts">
import type { MapViewport } from "@/components/ui/map";

const viewport = ref<MapViewport>({
  center: [-74.006, 40.7128],
  zoom: 11,
  bearing: 0,
  pitch: 0,
});
</script>

<template>
  <div class="relative h-[420px] w-full">
    <ClientOnly>
      <Map v-model:viewport="viewport" />
    </ClientOnly>
    <div
      class="bg-background/95 border-border/50 absolute top-3 left-3 z-10 rounded-lg border px-3 py-2 text-xs shadow backdrop-blur-md"
    >
      <p class="text-muted-foreground">
        Center
        <span class="text-foreground tabular-nums">
          {{ viewport.center[0].toFixed(3) }},
          {{ viewport.center[1].toFixed(3) }}
        </span>
      </p>
      <p class="text-muted-foreground">
        Zoom
        <span class="text-foreground tabular-nums">
          {{ viewport.zoom.toFixed(2) }}
        </span>
      </p>
    </div>
  </div>
</template>

Custom Styles

Use the styles prop to provide custom map styles. This example uses free vector tiles from OpenFreeMap, an open-source project sourcing data from OpenStreetMap.

<script setup lang="ts">
const styles = {
  light: "https://tiles.openfreemap.org/styles/positron",
  dark: "https://tiles.openfreemap.org/styles/dark",
};
</script>

<template>
  <div class="h-[420px] w-full">
    <ClientOnly>
      <Map :center="[-74.006, 40.7128]" :zoom="11" :styles="styles" />
    </ClientOnly>
  </div>
</template>