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.
Every block here ships in React and Vue. The React-only templates (business-locator-01, local-guide-01, public-notices-01, map-story-01) and the small examples are in the gallery, beside these blocks.
| Block | What 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. |
directions | Two 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-map | Interprovincial 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. |
census-choropleth | Provinces and territories coloured by 2021 Census population, change since 2016 or density, joined by id with feature-state. |
land-treaty-inspector | The survey cell at a point or a legal land description, hatched, beside the treaty records there, dotted. Legal land needs the Legal Land add-on (Energy and Agriculture include it). |
address-playground | Search with no map, in English, French and Inuktitut syllabics: every name a result carries, its details, and the nearest places of a category. |
energy-explorer | Alberta wells, pipelines and facilities with UWI search, a layer legend and click-to-identify. Needs the Energy add-on. |
ski-resort-explorer | Every Canadian ski area on the winter style in 3D, with search, province and activity filters, and the picked area's vertical, runs, lifts, aspect and drive time. Needs the Ski add-on. |
view-explorer | "Find the view": Calgary in 3D, click a building and its view opens west as one surface in the air from its window, scored, with the skyline you would see and 15 named summits marked in sight or hidden. |
urban-noise-map | "Check how loud a street is": modelled road, rail, aircraft and commercial noise in six cities, a Day / Night switch that recolours the map, and a clicked or searched spot's level against the WHO guideline, with a bar per source. Needs the Urban Noise add-on. |
alive-route-explorer | "Find a livelier walk": the fastest walk and livelier detours past parks, the river, streets away from traffic, cafés and public art, with dials that re-rank them without calling the API. |
Where the page goes
npx @unmap/cli add store-locator, or the shadcn commands under each block 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/. unmap add installs every block; the shadcn commands work too.
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.
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).
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/store-locatornpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/store-locator.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_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 },
});
});See the whole block running in the gallery.
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).
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/directionsnpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/directions.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_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 },
});
});See the whole block running in the gallery.
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.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/flow-mapnpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/flow-map.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "muted",
mode: "light",
center: [-88, 52],
zoom: 2.7,
});See the whole block running in the gallery.
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 the active DEM (mixed source models and datums from global release 6). 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).
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/elevation-explorernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/elevation-explorer.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_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`);
});See the whole block running in the gallery.
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).
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/delivery-trackernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/delivery-tracker.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_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 },
});
});See the whole block running in the gallery.
Compare provinces and territories
The provinces and territories from the 2021 Census, coloured by population, change since 2016 or density per km², with a legend that lists each class's provinces and the number for whatever the pointer is on. The shapes are GeoJSON joined to the census table by province code with feature-state, so switching the metric writes thirteen feature states instead of new data; swap in your own shapes and numbers keyed by any property and the join works the same. It ships the Statistics Canada 2021 Census Boundary Files for the provinces and territories and Table 98-10-0001-01 (Statistics Canada Open Licence), credited on the page, and calls no API beyond the map itself. The preview below draws the block's opening view, population in five classes; the gallery shows the whole block.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/census-choroplethnpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/census-choropleth.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "muted",
mode: "light",
center: [-96, 62],
zoom: 2.3,
});See the whole block running in the gallery.
Look up legal land and treaties
Search a legal land description or click the map: the survey cell there is hatched, every survey unit at the point is listed, and the treaty records at that point are dotted on the map beside the treaty panel. Legal land needs the Legal Land add-on (Energy and Agriculture include it). The block checks once whether your key holds it and, if not, says why (no add-on, the dev plan used from a production origin, or this month's development allowance spent), links the pricing page and keeps the treaty context, which every plan includes. Treaty context is the Crown's published representation of historic and modern treaties (Crown-Indigenous Relations and Northern Affairs Canada, Open Government Licence), not a map of Indigenous nations or a determination of rights. One add-on check on load, then /identify and /geocode/reverse for each point, and /geocode/autocomplete as you type a description.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/land-treaty-inspectornpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/land-treaty-inspector.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "muted",
overlays: ["treaties", "survey.dls"],
center: [-114.0719, 51.0447],
zoom: 11,
});See the whole block running in the gallery.
Look up any place in Canada
Search with no map, in English, French or Inuktitut syllabics: ᐃᖃᓗᐃᑦ finds Iqaluit. A chosen result lists every name it carries, each marked with its language, and its type, precision, match and source; six categories list the nearest places within 2 km. Few communities carry an Inuktitut name in the data yet, which is a gap in the sources, not in the search. Calls /geocode/autocomplete as you type (and /geocode/reverse when you type coordinates) and /geocode/nearby for each category.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/address-playgroundnpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/address-playground.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({ key: "um_pk_live_..." });
const results = await unmap.geocoder.autocomplete("iqaluit", { limit: 5, lang: "en" });See the whole block running in the gallery.
Explore Alberta's wells and pipelines
Alberta wells, pipelines and facilities from Alberta Energy Regulator open data, with a layer legend, UWI and licence search, and click-to-identify that shows whatever is recorded at a point. Search and identify answer from what the energy index holds, and the panel says so plainly when a UWI or a point has no record. It needs the Energy add-on: without it the map shows the basemap and the panel explains why and links the pricing page, instead of mounting search and identify that could only be refused. One add-on check on load, then /geocode/autocomplete for each search and /identify for each click.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/energy-explorernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/energy-explorer.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "muted",
profile: "energy",
center: [-114.98, 53.2],
zoom: 9,
});See the whole block running in the gallery.
Explore Canada's ski areas
Every ski area in Canada on the winter style over 3D terrain, from OpenStreetMap: search by name, filter by province or territory, and switch between downhill and nordic. Picking an area flies to it and tilts the camera onto its terrain, and the panel shows its vertical, top and base, runs (count, downhill and nordic kilometres), lifts, an eight-direction aspect readout and the drive time from the nearest city. The data is © OpenStreetMap contributors under the ODbL, which the panel credits, and it is terrain information only, not avalanche or safety advice. It needs the Ski add-on: without it the map still draws the winter style in 3D and the panel explains why and links the pricing page. Calls /ski/areas on load and again for each filter change; picking an area makes no call. Set lifts3d to draw the picked area's lift cables in 3D on its terrain: it is off by default, it loads @unmap/deck (deck.gl) only when an area is picked, and each pick then calls /ski/areas/{id}/lifts-3d once. Pass area and onAreaChange (v-model:area in Vue) to keep the picked area in your page URL: the block reports a readable slug of the area's name, such as nakiska, and area takes that slug or the area's id.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/ski-resort-explorernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/ski-resort-explorer.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "winter",
overlays: ["ski"],
center: [-122.92, 50.09],
zoom: 12,
});See the whole block running in the gallery.
Find the view
Can you see the Rockies from this home? Calgary in 3D, looking west. Click any building, or one of four sample spots (Patterson, Signal Hill, Crescent Heights, Inglewood), and the view from its window opens west as one see-through surface in your primary colour, leaving the window at its height and running out until it meets the ground. Its far edge is bright where it strikes the mountains and grey where a nearer hill cuts it short. The panel scores the view ("Mountain view: 69% of the western horizon"), draws the skyline you would see from that window and marks 15 named summits in sight or hidden. Summit names come from the Canadian Geographical Names Database (Open Government Licence – Canada). The Downtown toggle asks the same of the downtown towers, with one sight line from the window to their tops, and draws the ground between as a cross-section. The surface is drawn by deck.gl through @unmap/deck, loaded on the first pick, so the map alone never loads it.
Every height comes from the map's own /terrain tiles, read in the browser: fine tiles near the home, where a neighbour's rise decides the view, and coarse ones in the mountains. The first home reads about 25 tiles, most of them already loaded by the map; a nearby home reads a few more, and a home you look at again reads none. The sight lines account for the curve of the Earth with standard refraction, which hides about 600 m of mountain at 100 km. Elevation comes from the active DEM; supplier credits are at unmap.dev/attribution. It needs no add-on.
It uses terrain only: bare ground, so houses and trees are not counted, and the panel says so.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/view-explorernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/view-explorer.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "outdoor",
center: [-114.62, 51],
zoom: 9.6,
});See the whole block running in the gallery.
Check how loud a street is
How loud is it here, by day and at night? Modelled noise from road, rail, aircraft and commercial sources in Calgary, Edmonton, Vancouver, Toronto, Montréal and Québec City, drawn as the urban-noise overlay on the muted style, with a legend. The Day / Night switch recolours the whole map, from the day-evening-night level (Lden, stepped at 45, 53, 60 and 65 dB) to the night level (Lnight, 23:00 to 07:00, stepped at 40, 45, 50 and 55 dB). In both, the second step is the WHO 2018 guideline for road traffic, 53 dB Lden and 45 dB Lnight, so every warm colour is above it, and the legend draws that line. The switch makes no request: both levels are in the tiles.
Click the map or search an address and the card answers for that spot: the level for the period the map shows as the headline, day and night each on a bar against the WHO line with "above" or "within" in words, the WHO-anchored score (100 is quiet) with its label, the main source, and a bar per source. A searched address eases into view at street zoom; a click leaves the camera where you put it. A spot with no modelled source in range says so, never 0 dB and never quiet, and a place outside the six cities is said to be not covered, with the cities to jump to.
The levels are modelled, not measured: a screening estimate, not a compliance assessment, and the panel says so. They are computed from OpenStreetMap, so the data is © OpenStreetMap contributors under the ODbL, credited with the PickYourPlace noise model on the panel and in the map attribution. It needs the Urban Noise add-on: without it the map still draws and the panel explains why and links the pricing page. Calls /noise/point once per clicked or searched spot and /geocode/autocomplete as you type, after one add-on check. Pass period and onPeriodChange (v-model:period in Vue) to keep Day or Night in your page.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/urban-noise-mapnpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/urban-noise-map.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "muted",
center: [-114.07, 51.045],
zoom: 12,
});See the whole block running in the gallery.
Find a livelier walk
Walking directions that trade a minute for a nicer walk. Pick a start and a destination, or one of three Calgary samples, and get directions: the block finds the fastest walk, then detours past parks, the river, streets away from traffic, cafés and shops, and public art, and scores every walk on those five signals. Parks, water and streets come from the basemap tiles, read in the browser; cafés, shops and landmarks come from POST /places/along. Five dials say what counts and an extra-time budget says how much longer you will walk; moving them re-ranks the walks at once and calls nothing. The pick is drawn in your --primary and the fastest walk dashed in your --muted-foreground, each with a time bubble, and illustrated cards point at the first park, the busiest street and the first landmark the pick passes. A "Why this route" card shows the five scores beside the fastest walk's.
One search spends at most 40 calls: one /route for the fastest walk, up to 24 basemap tiles read for scoring (the map's own display tiles are separate), two POST /places/along, then /route pairs for detours and /match for paths the block finds on a walking graph in your browser. The answer is kept for each start and destination, so asking again costs nothing, unless a source was unavailable; the search boxes call /geocode/autocomplete as you type. When /places/along is unavailable the ranking uses parks, water and streets away from traffic only, and when the basemap tiles cannot be read it leaves those three out; either way their dials turn off, the "Why this route" card says "Unavailable", and the panel says so. The start and destination go to onEndsChange (React) or the ends-change event (Vue) whenever the reader changes them, so a page can keep them in its URL. The block draws its own illustrations; pass pictures (image URLs keyed by highlight kind, such as park, or by place category, such as food.cafe, each a list of variants) to show your own, which are tagged "Illustration" with alt text saying they are AI-generated. title and badge set the panel's heading and a short tag beside it. It reads the basemap tiles through @unmap/maps/tiles, which first ships in @unmap/maps 0.30.0, so the item asks for @unmap/maps@^0.30.0: an install before that release fails at install time rather than at runtime.
npx shadcn@latest registry add @unmap=https://registry.unmap.dev/r/{name}.json
npx shadcn@latest add @unmap/alive-route-explorernpx shadcn-vue@latest add https://registry.unmap.dev/r/vue/alive-route-explorer.jsonThe 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.devimport { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_pk_live_...",
container: "map",
style: "tropic",
center: [-114.0495, 51.05],
zoom: 14,
});See the whole block running in the gallery.