Skip to content

Blocks

A block is a page rather than a component: it composes the registry items into a screen that calls the unmap API with your key, and where it needs data it ships with open sample data, credited on the page. add installs the page and every item it uses. Each preview below makes the same kind of API call as its block, on this site's demo key.

BlockWhat it is
store-locator"Find a branch": search a place, see the branches near it clustered with a list that follows the map, the drive-time area round the one you pick, and directions to it.
directionsTwo search boxes and a drive, cycle or walk switch that redraws the route and the reachable area for that mode, with the travel time as the headline.
flow-mapInterprovincial migration from Statistics Canada drawn as flows between the capitals, with a year scrubber and each province's net in and out.
elevation-explorer"See the climb": a trip, a route between two searches or a drawn line, its elevation profile, and the line coloured by grade.
delivery-tracker"Track a delivery": a route from a depot to a drop-off, a courier moving along it and the arrival time.

Where the page goes

npx @unmap/cli add store-locator, or the shadcn commands on each card below, puts the page at app/store-locator/page.tsx in a Next.js App Router project or at app/pages/store-locator.vue in a Nuxt 4 project, and the block's component in components/ui/. Every block ships in both lanes. unmap add installs blocks from @unmap/cli 0.15.0 on (0.14.0 answers "unknown item"); the shadcn commands work with any version.

On Nuxt, prefer unmap add. The shadcn-vue command assumes the app/ layout: it always writes app/pages/<name>.vue and wires no key, and on a project that keeps app.vue at the root, a new app/ folder moves Nuxt's source directory and breaks the app. unmap add puts the page where your layout reads it and declares the key.

A block installs the current version of the items it uses. If you already have an older flow-layer or elevation-profile, accept shadcn's prompt to overwrite it, or pass --overwrite.

The page reads your key from NEXT_PUBLIC_UNMAP_KEY in .env.local on Next.js, and from NUXT_PUBLIC_UNMAP_KEY through runtimeConfig.public.unmapKey on Nuxt. On Nuxt, unmap add writes the empty NUXT_PUBLIC_UNMAP_KEY line to .env (or leaves it where you already set it) and adds runtimeConfig.public.unmapKey to nuxt.config; on the Nuxt 3 layout it moves the page into pages/. Paste your key after the install. In any other project (Vite, plain Vue) the shadcn CLIs skip the page, so render the component yourself: <StoreLocator apiKey={key} /> or <UnmapStoreLocator :api-key="key" />. With no key, a block shows where to get one and which variable to set, and loads nothing. unmap create --only refuses blocks; add one to a project with unmap add.

Metering is per request. The map's own style and tile requests count as they do on any unmap map, and each block adds only the requests listed in its section below, one for each answer, made when the reader acts. If your key only accepts certain origins, add http://localhost:3000 while you develop.

Find a branch

Search a place and the map pulls in to it and its nearest branches, clustered as you zoom, with a list that follows the view and answers the map when you hover either. Pick a branch for its hours, the area within a 10-minute drive round it (driveMinutes changes it) and directions. Calls /geocode/autocomplete (and /geocode/reverse when you type coordinates), /isochrone and /route. It ships with the 33 Ottawa Public Library branches from City of Ottawa open data, credited under the Open Government Licence, City of Ottawa; pass stores for your own points. Routes and drive areas carry the OpenStreetMap contributors credit (ODbL).

Copy this component into your project (store-locator)
React
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/store-locator
Vue and Nuxt
npx shadcn-vue@latest add https://registry.unmap.dev/r/vue/store-locator.json

The React line registers the registry once per project, so later items can be named @unmap/<item>; shadcn-vue has no registry add and takes the item URL directly. Files land in components/ui/ beside your own; nothing is overwritten without asking.

Browse every item on registry.unmap.dev
live result
the code that produced it
import { Unmap } from "@unmap/sdk";

const unmap = new Unmap({
  key: "um_live_...",
  container: "map",
  center: [-75.69, 45.42],
  zoom: 11,
});

const bands = await unmap.router.isochrone([-75.69, 45.42], { minutes: [10], mode: "auto" });

unmap.map!.on("load", () => {
  unmap.map!.addSource("bands", { type: "geojson", data: bands });
  unmap.map!.addLayer({
    id: "bands-fill",
    type: "fill",
    source: "bands",
    paint: { "fill-color": "#FF3E9A", "fill-opacity": 0.18 },
  });
});

Get directions

Two search boxes, then the route and its travel time as the headline. The travel-mode switch (drive, cycle, walk) is the point: it redraws the route for that mode, keeps each mode's time on the switch so they compare at a glance, and the reachable area follows the mode and needs only a start. Calls /geocode/autocomplete (and /geocode/reverse when you type coordinates), /route once per mode and /isochrone once per start and mode; each answer is asked for once and remembered for the current start and destination. The routing API returns one route per request, so the block shows no alternative routes. It ships no data; routes carry the OpenStreetMap contributors credit (ODbL).

Copy this component into your project (directions)
React
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/directions
Vue and Nuxt
npx shadcn-vue@latest add https://registry.unmap.dev/r/vue/directions.json

The React line registers the registry once per project, so later items can be named @unmap/<item>; shadcn-vue has no registry add and takes the item URL directly. Files land in components/ui/ beside your own; nothing is overwritten without asking.

Browse every item on registry.unmap.dev
live result
the code that produced it
import { Unmap } from "@unmap/sdk";

const unmap = new Unmap({
  key: "um_live_...",
  container: "map",
  center: [-114.0719, 51.0447],
  zoom: 10,
});

const bands = await unmap.router.isochrone([-114.0719, 51.0447], { minutes: [10, 20, 30], mode: "auto" });

unmap.map!.on("load", () => {
  unmap.map!.addSource("bands", { type: "geojson", data: bands });
  unmap.map!.addLayer({
    id: "bands-fill",
    type: "fill",
    source: "bands",
    paint: { "fill-color": "#FF3E9A", "fill-opacity": 0.18 },
  });
});

Follow interprovincial migration

Interprovincial migration from Statistics Canada (Table 17-10-0022-01, 2021/2022 to 2025/2026, Statistics Canada Open Licence) drawn with flow-layer between the provincial and territorial capitals, with a year scrubber from time-slider. Line widths sit on one scale across the years, so a year with more moves draws wider lines, and each province shows its net in and out. The 2025/2026 estimates are preliminary and the block says so. It calls no API beyond the map itself.

Copy this component into your project (flow-map)
React
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/flow-map
Vue and Nuxt
npx shadcn-vue@latest add https://registry.unmap.dev/r/vue/flow-map.json

The React line registers the registry once per project, so later items can be named @unmap/<item>; shadcn-vue has no registry add and takes the item URL directly. Files land in components/ui/ beside your own; nothing is overwritten without asking.

Browse every item on registry.unmap.dev
live result
the code that produced it
import { Unmap } from "@unmap/sdk";

const unmap = new Unmap({
  key: "um_live_...",
  container: "map",
  style: "muted",
  mode: "light",
  center: [-96, 58],
  zoom: 3,
});

See the climb

Pick one of three mountain trips, route your own from two searches, or draw a line, and read its profile from /elevation, sampled along the line from NRCan's MRDEM-30 model (Open Government Licence, Canada). The line takes the colour of its grade from the same samples: descents in your primary colour, flat stretches muted and climbs in your destructive colour, all from your tokens. The chart and the line answer each other on hover. A profile is one request for up to 500 samples and a line you return to comes from the block's cache, so it costs nothing; a trip or a route adds one /route request, and the search boxes call /geocode/autocomplete (and /geocode/reverse for typed coordinates).

Copy this component into your project (elevation-explorer)
React
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/elevation-explorer
Vue and Nuxt
npx shadcn-vue@latest add https://registry.unmap.dev/r/vue/elevation-explorer.json

The React line registers the registry once per project, so later items can be named @unmap/<item>; shadcn-vue has no registry add and takes the item URL directly. Files land in components/ui/ beside your own; nothing is overwritten without asking.

Browse every item on registry.unmap.dev
live result
the code that produced it
import { Unmap } from "@unmap/sdk";

const unmap = new Unmap({
  key: "um_live_...",
  container: "map",
  center: [-116.18, 51.43],
  zoom: 11,
});

const [metres] = await unmap.elevation.get([-116.18, 51.43]);

unmap.map!.on("click", async (e) => {
  const [here] = await unmap.elevation.get([e.lngLat.lng, e.lngLat.lat]);
  console.log(here === null ? "no data here" : `${here} m`);
});

Track a delivery

A route from /route drawn with route-line, from a depot to the drop-off you pick, the travelled part filling in as a courier marker moves along it, and an arrival time on a card that counts down. The courier is played back along the route's own geometry at 30 times real time, so a delivery is one request and Restart makes no new one; swap the playback for your fleet's positions to track real couriers. The depot and drop-offs are Ottawa Public Library branches (City of Ottawa open data, Open Government Licence, City of Ottawa); routes carry the OpenStreetMap contributors credit (ODbL).

Copy this component into your project (delivery-tracker)
React
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/delivery-tracker
Vue and Nuxt
npx shadcn-vue@latest add https://registry.unmap.dev/r/vue/delivery-tracker.json

The React line registers the registry once per project, so later items can be named @unmap/<item>; shadcn-vue has no registry add and takes the item URL directly. Files land in components/ui/ beside your own; nothing is overwritten without asking.

Browse every item on registry.unmap.dev
live result
the code that produced it
import { Unmap } from "@unmap/sdk";

const unmap = new Unmap({
  key: "um_live_...",
  container: "map",
  center: [-75.689, 45.425],
  zoom: 14,
});

const route = await unmap.router.route([-75.695396, 45.4203], [-75.683098, 45.430099], { mode: "auto" });

unmap.map!.on("load", () => {
  unmap.map!.addSource("route", {
    type: "geojson",
    data: { type: "Feature", properties: {}, geometry: route.geometry },
  });
  unmap.map!.addLayer({
    id: "route-line",
    type: "line",
    source: "route",
    layout: { "line-cap": "round", "line-join": "round" },
    paint: { "line-color": "#FF3E9A", "line-width": 3 },
  });
});