Map
The map container. Handles Mapbox GL setup, light/dark theming, Standard styles, and provides context for child components.
Basic Usage
Wrap your map in <Map>. It reads your token from NEXT_PUBLIC_MAPBOX_TOKEN and follows the document theme automatically.
import { Map } from "@/components/ui/map";
export function BasicMapExample() {
return (
<div className="h-[420px] w-full">
<Map center={[-97.7431, 30.2672]} zoom={11} />
</div>
);
}
Theming
By default <Map> follows your site theme: it watches the light / dark class on <html> (the one next-themes toggles) and swaps the basemap live. No configuration needed.
To pin the basemap to a fixed theme and stop it reacting to site theme changes, pass theme:
<Map theme="dark" />To change which Mapbox style each theme maps to, pass styles:
<Map
styles={{
light: "mapbox://styles/mapbox/streets-v12",
dark: "mapbox://styles/mapbox/dark-v11",
}}
/>theme is the off switch for automatic theme following - the map will ignore the document theme entirely until you remove it.Styles & Modes
Theme switching is for light/dark basemaps. To pin a single fixed style regardless of theme - including the 3D Standard style - pass mapStyle. It takes precedence over theme / styles and turns off automatic swapping.
<Map mapStyle="mapbox://styles/mapbox/standard" />The Standard style ships four light presets - day, dusk, dawn, night. Set one with lightPreset; it is re-applied across style swaps and ignored by classic styles that don't expose it.
Here it is live - the buttons swap lightPreset on the same map:
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Map, type LightPreset } from "@/components/ui/map";
const presets: LightPreset[] = ["day", "dusk", "dawn", "night"];
export function MapModesExample() {
const [preset, setPreset] = useState<LightPreset>("day");
return (
<div className="relative h-[420px] w-full">
<Map
mapStyle="mapbox://styles/mapbox/standard"
lightPreset={preset}
center={[-97.7426, 30.2668]}
zoom={15.5}
pitch={55}
bearing={-20}
/>
<div className="absolute top-3 left-3 z-10 flex gap-1 rounded-md border bg-background/80 p-1 backdrop-blur">
{presets.map((value) => (
<Button
key={value}
type="button"
size="sm"
variant={preset === value ? "default" : "ghost"}
className="capitalize"
onClick={() => setPreset(value)}
>
{value}
</Button>
))}
</div>
</div>
);
}
Props
Any other mapboxgl.MapOptions (such as center, zoom, pitch) are passed straight to the map.
| Prop | Type | Default | Description |
|---|---|---|---|
theme | "light" | "dark" | — | Basemap theme. Follows the document theme when omitted; set it to pin a theme and disable automatic switching. |
styles | { light?: string; dark?: string } | — | Override the default Mapbox styles per theme. |
mapStyle | string | — | A single fixed style URL. Overrides theme/styles and disables automatic swapping. |
lightPreset | "day" | "dusk" | "dawn" | "night" | — | Light preset for the Standard style. Ignored by styles without one. |
accessToken | string | NEXT_PUBLIC_MAPBOX_TOKEN | Mapbox access token. |
className | string | — | Classes for the map container. |