Install the toolbar, integrate it with your preferred map library, tune its behavior with
configuration, customize its appearance with CSS variables, and understand the public API.
Mapalizer overlays location-quality scoring on real estate maps without showing raw
POI clutter. The toolbar lets visitors weight categories such as transit, dining, parks,
shopping, health, and daily essentials, then visualizes the result directly on the map.
The toolbar reads the current viewport and selected user preferences.
Mapalizer requests score layers and supporting locale data from the Mapalizer CDN.
The map displays score layers that can be toggled on or off.
The same state can be queried programmatically through the public JavaScript API.
How scoring works
Each real-estate-relevant place (selected from OpenStreetMap Features) belongs to a subcategory, and each subcategory has its own maximum score and its own maximum distance. As distance increases, that contribution decreases linearly until it reaches zero at the configured maximum distance.
For example, two different restaurants standing side-by-side will not have a greater impact than the maximum score that can be obtained from the "Restaurant" subcategory. In this way, different subcategories are added together to determine the main category score between 0 and 1.
When calculating the score of a point on the map, the average score of the categories selected from the Mapalizer Toolbar at that point is taken into account. By default, all selected categories are weighted the same when calculating the average score.
Getting Started
A simple launch checklist for your Mapalizer setup.
1
Create account and register your sites
Create your account at portal.mapalizer.com, then add the websites where Mapalizer is allowed to load.
2
Create API tokens
Generate publishable API tokens for each site at portal.mapalizer.com/tokens and keep test and production usage separate.
3
Install Mapalizer
Add the async loader in your page <head>. See Installation for setup details.
4
Use Mapalizer
Choose your integration path — toolbar on a map, score widget, or scores only. See Use Mapalizer for details.
5
Try Configurator and Toolbar Themes
Use the Configurator to define your starting settings, then explore Toolbar Themes to find the style that fits your website best.
The recommended installation pattern is an asynchronous loader in the page
<head>. It creates the global
mapalizer object immediately and queues calls until the
runtime bundle finishes loading.
The toolbar exposes a small public API designed for site integration and state-aware
workflows. Each method below has its own anchor, input contract, and return shape.
Scan root (or the full document) for [data-mpl-widget] elements and initialise any that have not been rendered yet.
mapalizer.addToMap(map, config?)
Initializes Mapalizer on a supported map instance and injects the toolbar UI.
Parameter
Type
Required
Description
map
Object
Yes
Google Maps, Leaflet, or Mapbox map instance.
config
Object
No
Configuration object. Include auth.siteToken for test and production websites. See Configuration Object.
Returns:Promise<{ ok: boolean, error?: string, status?: number }>. The toolbar is only inserted into the page after authentication succeeds. Use await or .then() to react to the outcome.
Live-updates settings for an active toolbar. Only the keys you include in partialConfig are applied — all other settings remain unchanged.
Parameter
Type
Required
Description
map
Object
Yes
The map instance the toolbar is attached to.
partialConfig
Object
Yes
Partial config object. Any subset of the fields below.
partialConfig fields
Field
Type
Description
language
String
Switch the toolbar UI language. Also updates the inherited default for future addToMap() calls. Supported language code list: .
theme
String
Switch the toolbar theme. Supported values: 'light', 'dark'.
toolbar.activeState
Boolean
Programmatically enable (true) or disable (false) the toolbar. Does not fire mapalizer:statechange — programmatic toggles carry no side effects; the event is reserved for user-initiated actions (which also trigger tile prefetching).
Contour visibility threshold (0–1). Same path as the drag handle in the colour bar.
layer.contourColors
Array<String>
Array of hex colour values for contour lines. Triggers a layer and colour-bar redraw.
layer.transitionDuration
Number
SVG tile fade duration in milliseconds. Takes effect on the next tile transition — no immediate redraw.
categories
Object
Selectively update category selection state. Only isSelected is accepted per key — weight, icon, and sortOrder are init-only. Keys are case-insensitive; unknown keys are skipped with a warning. Fires mapalizer:statechange (type CATEGORIES) only when at least one isSelected value actually changes — passing the same selection state is a no-op and dispatches no event. See category key map.
Returns:Boolean. true if the toolbar was found and updated, false if no toolbar is attached to the given map.
Scores arbitrary geographic coordinates. Pass options.map to read from
a live toolbar attached to that map instance (map-attached mode), or omit it
to score without any map or toolbar (standalone mode). Tiles are fetched in
parallel, deduplicated by tile, and cached in memory for subsequent calls.
Parameter
Type
Required
Description
points
Array<{ lat: number, lng: number }>
Yes
Coordinates to score, returned in the same order as the input array.
options
Object
No
Options object. Omit entirely for standalone mode, or pass at minimum { map } for map-attached mode.
options fields
Field
Type
Mode
Description
map
Object
Map-attached
The map instance the toolbar is attached to. When present, all other options are ignored; toolbar state is read live.
verticalKey
String
Standalone
Data vertical to score against. Currently only 're' (real estate) is supported. Defaults to 're'.
auth.siteToken
String
Standalone
Publishable site token from portal.mapalizer.com. Required everywhere. Use a mpl_pk_test_ token on localhost and a mpl_pk_live_ token on real domains.
language
String
Standalone
Language code for localizedTitle values in the response (e.g. 'de', 'fr'). Defaults to English. Ignored in map-attached mode (toolbar language is used instead). Supported language code list: .
categories
Object
Standalone
Selectively exclude categories from the totalScore calculation. In standalone mode all categories start as isSelected: true (there is no toolbar UI to drive selection), so totalScore reflects every category by default. Pass { [key]: { isSelected: false } } to opt specific categories out of the weighted total. Has no effect on individual category scores — only on which categories contribute to totalScore. See category key map for available keys.
Returns:Promise<GetScoresResult>.
GetScoresResult
{
ok: Boolean,
error: String | undefined, // only present when ok is false
toolbar: {
activeState: Boolean | null,
contourThreshold: Number | null
},
categories: {
TRANSIT: {
title: String,
localizedTitle: String,
isSelected: Boolean,
weight: Number,
sortOrder: Number
}
// ESSENTIALS … CULTURE
},
results: [
{
lat: Number,
lng: Number,
dataFound: Boolean,
scores: { TRANSIT: Number /* …CULTURE */ } | null,
totalScore: Number | null,
aboveThreshold: Boolean | null
}
]
}
Field
Type
Description
ok
Boolean
true when scoring succeeded; false on auth or configuration failure. Check this before reading results.
error
String | undefined
Error code when ok is false. Values: 'toolbox_not_found', 'browser_not_supported', 'invalid_settings', 'missing_site_token', 'auth_failed'.
toolbar.activeState
Boolean | null
Whether the toolbar is currently on. Always null in standalone mode.
toolbar.contourThreshold
Number | null
Current threshold in the 0-1 range. Always null in standalone mode.
categories
Object
Current category metadata and selection state keyed by title (e.g. TRANSIT, ESSENTIALS). See category key map.
results
Array<Object>
One result per input point, in the same order as the input. Each item uses the structure below.
results[] item
Field
Type
Description
lat
Number
Echoed-back latitude from the input point.
lng
Number
Echoed-back longitude from the input point.
dataFound
Boolean
false means there is no tile coverage for this coordinate.
scores
Object | null
Per-category raw scores keyed by title (e.g. TRANSIT, ESSENTIALS), each in the 0-1 range.
totalScore
Number | null
Weighted aggregate score in the 0-1 range, rounded to 2 decimals.
aboveThreshold
Boolean | null
true, false, or null when threshold comparison is inactive (standalone mode or toolbar off).
Map-attached mode
// Only selected categories contribute to totalScore
const response = await mapalizer.getScores([
{ lat: 52.505, lng: 13.389 },
{ lat: 48.858, lng: 2.295 }
], { map });
if (response.ok) {
response.results.forEach(function (result) {
if (!result.dataFound) {
console.log(result.lat, result.lng, '— no data coverage');
} else {
console.log(result.lat, result.lng, '— score:', result.totalScore);
}
});
}
Listen for state changes when you want your application to react to threshold updates,
category selection, or toolbar on/off toggles. Category keys use the title-based format
shown in the category key map (e.g. TRANSIT, ESSENTIALS).
Dispatched on window when the async loader has finished loading the runtime bundle and flushed all queued calls. This is the recommended signal to use when you need the return value from addToMap() or renderWidget() — both methods return meaningful results only after the library is fully loaded.
Dispatched on window when the async loader fails to initialise — for example if the bundle script fails to load or the browser is not supported. Use this to show a fallback or suppress further Mapalizer calls.
window.addEventListener('mapalizer:failed', function (e) {
console.warn('Mapalizer could not load:', e.detail);
});
mapalizer.renderWidget(element, point, options?)
Renders a self-contained score-badge widget into element for a single geographic coordinate. Works in two modes: map-attached (inherits auth and settings from a live toolbar) or standalone (no map required — supply a siteToken).
Returns a Promise that always resolves (never rejects). On success the promise value includes a destroy() function to remove the widget and the raw scores object.
// Map-attached — inherits auth from the toolbar on googleMapInstconst { ok, scores, destroy } = await mapalizer.renderWidget(
document.getElementById('my-widget'),
{ lat: 52.52, lng: 13.405 },
{ map: googleMapInst }
);
// Standalone — no map neededconst result = await mapalizer.renderWidget(
document.getElementById('my-widget'),
{ lat: 52.52, lng: 13.405 },
{ auth: { siteToken: 'mpl_pk_live_…' } }
);
if (result.ok) console.log(result.scores);
Options
Option
Type
Default
Description
map
Map instance
—
Map-attached mode. Inherits auth, vertical, language, and theme from the toolbar already added to this map.
auth.siteToken
string
—
Required in standalone mode. Your publishable site token.
verticalKey
string
're'
Standalone mode only. Data vertical (e.g. 're' for real estate).
language
string
'en'
BCP 47 language code for category labels (e.g. 'de', 'fr'). Supported language code list: .
theme
'light' | 'dark'
'light'
Visual theme. In map-attached mode defaults to the toolbar theme.
categories
string[]
all
Restrict which category badges are shown. E.g. ['TRANSIT','ESSENTIALS','HEALTH'].
excludeCategories
string[]
none
Exclude specific category keys before rendering. This is especially meaningful when used with showTopCategories.
showTopCategories
integer ≥ 1
—
Show only the top N categories sorted by score descending.
title
string | null
locale default
Widget heading. Pass null or '' to suppress the title.
You can exclude lessly used categories like Health and Culture with excludeCategories: ['HEALTH', 'CULTURE']. This is especially meaningful when used together with showTopCategories.
Return value
Property
Type
Description
ok
boolean
true on success.
error
string?
Error key when ok is false: invalid_element, invalid_settings, missing_site_token, auth_failed, no_data, toolbox_not_found, browser_not_supported, superseded.
scores
object?
Raw 0–1 scores keyed by category (e.g. { TRANSIT: 0.87, ESSENTIALS: 0.61, … }). Present only when ok is true.
destroy()
function
Removes the widget node from element. Idempotent. Safe to call even if a newer render has already replaced this one.
Your publishable site token (same as auth.siteToken).
data-lat
Yes
Latitude of the location to score.
data-lng
Yes
Longitude of the location to score.
data-language
No
BCP 47 language code for labels (e.g. de, fr). Defaults to en. Supported language code list: .
data-theme
No
light or dark. Defaults to light.
data-vertical
No
Data vertical key. Defaults to re (real estate).
data-categories
No
Comma-separated category keys to show (e.g. TRANSIT,ESSENTIALS,HEALTH). Defaults to all categories.
data-show-top
No
Show only the top N categories sorted by score. E.g. 4.
data-exclude-categories
No
Comma-separated category keys to exclude. Especially meaningful together with data-show-top; for example HEALTH,CULTURE excludes Health and Culture.
data-title
No
Widget heading. Omit for locale default. Set to "" to suppress the title entirely.
For elements rendered after page load (SPA route changes, CMS hydration), call mapalizer.initWidgets(root?) to initialise any new [data-mpl-widget] elements inside root.
CSS customisation
The widget root carries class mpl mpl-widget. All visual tokens are CSS custom properties on .mpl and should be overridden on .mpl itself, or via a selector that targets it.
Font family: The Mapalizer stylesheet sets the font on .mpl via --mpl-font-family with !important. Overriding font-family directly on .mpl-widget will not work — set the CSS variable on .mpl instead:
/* Override font for one widget */
#my-widget .mpl {
--mpl-font-family: 'Lato', sans-serif;
--mpl-font-size-base: 13px;
}
/* Or globally */
body .mpl {
--mpl-font-family: var(--app-font-family, Arial, sans-serif);
}
The unminified reference stylesheet is available at . Use it as a starting point when you need full control — disable automatic CSS injection with loadCss: false and host your own copy:
⚠️ Ring colours and badge geometry are intentionally not customisable. They encode score meaning and should remain consistent with the Mapalizer design language.
🌙 Dark mode is applied automatically when you pass theme: 'dark' — the .mpl.mpl-theme-dark modifier is added to the widget root. No extra CSS is needed from the host page.
mapalizer.initWidgets(root?)
Scans root (or the full document when omitted) for [data-mpl-widget] elements and calls renderWidget() for each one that has not been initialised yet. Already-rendered elements are skipped — calling initWidgets() multiple times is safe.
This method is called automatically on DOMContentLoaded, so elements present in the initial HTML require no manual call. You only need to call it explicitly for elements added to the DOM after page load.
When to use initWidgets() vs renderWidget()
renderWidget()
initWidgets()
Integration style
JavaScript-driven. You pass the element, coordinates, and options explicitly in code.
HTML-driven. Coordinates and options live in data-* attributes; no per-widget JavaScript is needed.
When to call
Any time — on page load, after a user action, or when coordinates arrive from an API.
After adding new [data-mpl-widget] elements to the DOM (SPA route change, CMS hydration, infinite scroll). For elements in the initial HTML, it is called automatically.
Return value
Promise<{ ok, scores, destroy }> — lets you handle success/error and control the widget lifecycle.
undefined — fire and forget.
Best for
Dynamic coordinates, result handling, or when you need the destroy() handle.
CMS pages, static HTML templates, or any setup where widget markup is generated server-side.
Scoping to a subtree
Pass a DOM element as root to limit the scan to that subtree. This is more efficient than scanning the whole document and avoids re-checking already-rendered content.
// SPA route change — only scan the newly mounted viewfunctiononRouteChange(newView) {
document.getElementById('app').replaceChildren(newView);
mapalizer.initWidgets(document.getElementById('app'));
}
// Full-document scan — rarely needed; runs automatically on DOMContentLoaded
mapalizer.initWidgets();
Programmatic Scoring
Use getScores() to score arbitrary coordinates. Pass options.map
to read from a live toolbar attached to that map, or omit it for standalone scoring — useful
for custom marker filtering, ranked side panels, or synchronizing map state with listing cards.
💡 Try it live: open the API Examples page, drop some markers, then open your browser DevTools (F12) and watch the Console tab — each getScores call prints the exact parameters used and the full response object so you can explore the result shape interactively.
Filtering markers on toolbar state changes
A common listing-page pattern is to grey out markers that fall below the active score threshold whenever the user adjusts the toolbar, and to restore them when the toolbar is turned off. The technique combines two APIs:
mapalizer:statechange — dispatched on window for every user-initiated change (toolbar toggle, threshold slider, category selection).
getScores(points, { map }) — returns threshold-aware results that reflect the current live toolbar state.
Debouncing is essential. The threshold slider fires mapalizer:statechange on every drag step. Use a short setTimeout / clearTimeout pair so that only one getScores() call is issued after the user finishes adjusting, rather than one per pixel of slider movement.
Always check response.toolbar.activeState before reading aboveThreshold. When the toolbar is off, every result.aboveThreshold is null — clear all grayed styling in that state rather than treating every marker as below-threshold.
Strategy A — Score each marker at its own position
Pass every visible listing coordinate to getScores() and apply the result directly to the corresponding marker. Best suited for pages with up to a few hundred visible markers and no clustering layer. This is the approach used in the API Examples demo.
// ── Step 1: Listing data ──────────────────────────────────────────────────
// One entry per visible listing. getScores() results are returned in the
// same order as the input array, so results[i] maps to listings[i].const listings = [
{ id: 'listing-1', marker: markerA, lat: 52.505, lng: 13.389 },
{ id: 'listing-2', marker: markerB, lat: 52.508, lng: 13.401 },
// …
];
// ── Step 2: Marker appearance ─────────────────────────────────────────────
// Toggle a CSS class or swap the icon to apply / clear the grayed state.
// Adapt this to your map library and icon implementation.functionsetMarkerGrayed(marker, grayed) {
// Google Maps AdvancedMarkerElement:
marker.content.classList.toggle('marker--grayed', grayed);
// Leaflet:// marker.getElement()?.classList.toggle('marker--grayed', grayed);
}
// ── Step 3: Apply scoring results ─────────────────────────────────────────
// Grays a marker when the toolbar is active AND the location falls below
// the current contourThreshold (aboveThreshold === false).functionapplyThresholdFilter(response) {
const active = response.toolbar.activeState;
response.results.forEach(function (result, i) {
const grayed = active && result.aboveThreshold === false;
setMarkerGrayed(listings[i].marker, grayed);
});
}
// ── Step 4: Debounced scoring request ─────────────────────────────────────
// Cancels any pending request and waits delayMs before issuing a new one.
// A generation counter discards stale async responses that arrive out of order.let refreshTimer = null;
let requestGen = 0;
functionscheduleFilterRefresh(delayMs) {
clearTimeout(refreshTimer);
refreshTimer = setTimeout(function () {
const gen = ++requestGen;
const points = listings.map(function (l) { return { lat: l.lat, lng: l.lng }; });
mapalizer.getScores(points, { map: map }).then(function (response) {
if (gen !== requestGen) return; // discard if a newer request has startedif (response.ok) applyThresholdFilter(response);
});
}, delayMs);
}
// ── Step 5: React to toolbar state changes ────────────────────────────────
// mapalizer:statechange fires for ACTIVE_STATE, CONTOUR_THRESHOLD, and
// CATEGORIES events. Use a longer debounce for the threshold slider
// (fires continuously during drag) than for instant toggle/click events.
window.addEventListener('mapalizer:statechange', function (e) {
if (e.detail.map !== map) return; // ignore events from other map instancesconst delay = e.detail.eventType === mapalizer.EventTypes.CONTOUR_THRESHOLD ? 180 : 80;
scheduleFilterRefresh(delay);
});
Strategy B — Score by cluster or group representative
When your map groups nearby markers into cluster bubbles, scoring one representative position per cluster is far more efficient than scoring every individual listing. A map with 1,000 markers spread across 80 clusters requires only 80 scoring points instead of 1,000. The listing demo uses this as its primary strategy, with a Strategy A fallback for when the clusterer is not yet active.
Only currently visible markers inside each cluster should be included — exclude any markers hidden by your own listing filters. For multi-marker clusters, score the cluster centre. For unclustered single markers, score the marker's own position for accuracy. Since getScores() returns results in the same order as the input, results[i] aligns directly with units[i] — no ID mapping needed.
// ── Step 1: Helpers ───────────────────────────────────────────────────────
// Normalize a map-library position to a plain { lat, lng } object.
// Google Maps uses LatLng objects with .lat()/.lng() methods; Leaflet uses plain objects.functiontoPoint(pos) {
returntypeof pos.lat === 'function' ? { lat: pos.lat(), lng: pos.lng() } : pos;
}
// Replace with your own visibility predicate — return false for markers
// currently hidden by listing filters (price, rooms, property type, etc.).functionisMarkerVisible(marker) { return !marker.hidden; }
// ── Step 2: Build cluster scoring units ───────────────────────────────────
// getClusters() must return the live cluster snapshot from your clustering
// library. Each cluster must expose:
// cluster.position — cluster centre (plain { lat, lng } or a LatLng object)
// cluster.markers — all markers inside the clusterlet refreshTimer = null;
let requestGen = 0;
functionscheduleClusterFilterRefresh(getClusters, delayMs) {
clearTimeout(refreshTimer);
refreshTimer = setTimeout(function () {
const gen = ++requestGen;
const clusters = getClusters();
if (!clusters || !clusters.length) return;
// Collect one scoring unit per cluster, skipping hidden markers.
// Single visible marker → score its own position (accurate).
// Multiple visible markers → score the cluster centre (representative).const units = [];
clusters.forEach(function (cluster) {
const visible = cluster.markers.filter(isMarkerVisible);
if (!visible.length) return; // skip fully-hidden clusters
units.push({
point: toPoint(visible.length > 1 ? cluster.position : visible[0].position),
markers: visible // keep direct references — results align by index
});
});
if (!units.length) return;
// ── Step 3: Score representative points and apply results ─────────────
// One getScores() call for all clusters instead of one per listing.
// response.results[i] aligns with units[i] by sequence.const points = units.map(function (u) { return u.point; });
mapalizer.getScores(points, { map: map }).then(function (response) {
if (gen !== requestGen) return; // discard if a newer request has startedif (!response.ok) return;
const active = response.toolbar.activeState;
units.forEach(function (unit, i) {
const grayed = active && response.results[i].aboveThreshold === false;
// Propagate the cluster score to every marker inside it.
unit.markers.forEach(function (m) { setMarkerGrayed(m, grayed); });
});
});
}, delayMs);
}
// ── Step 4: React to toolbar state changes ────────────────────────────────
// Same pattern as Strategy A. Fall back to Strategy A when getClusters()
// returns null (e.g. the clusterer has not initialised yet).
window.addEventListener('mapalizer:statechange', function (e) {
if (e.detail.map !== map) return;
const delay = e.detail.eventType === mapalizer.EventTypes.CONTOUR_THRESHOLD ? 180 : 80;
if (getClusters()) scheduleClusterFilterRefresh(getClusters, delay);
elsescheduleFilterRefresh(delay); // Strategy A fallback
});
Configuration Object
The optional second argument to addToMap() lets you tune the toolbar to your
layout, language, and product requirements.
Pass an object like this as the second argument to mapalizer.addToMap(map, config). For test and production websites, include auth.siteToken from portal.mapalizer.com.
Reference JSON for the current website release:
.
Loading current default settings…
toolbar
Property
Default
Description
activeState
Show the toolbar as active on initialization.
horizontal
Horizontal toolbar position: left or right.
vertical
Vertical toolbar position: top or bottom.
desktop.style
See example above
Desktop CSS positioning rules such as top, right, and z-index.
mobile.maxWidth
Breakpoint below which mobile behavior activates.
mobile.hidden
Hide the toolbar entirely on mobile if needed.
mobile.style
See example above
Mobile-specific positioning overrides.
desktop.style and mobile.style are filtered by the
chosen horizontal and vertical positions. For example, with
horizontal: 'right' and vertical: 'top', only the right
and top offsets are applied; the opposite side values are ignored.
layer
Property
Default
Description
opacity
Heat layer transparency from 0.0 to 1.0.
contourThreshold
Hide low-scoring contours below this default threshold.
contourColors
Low-to-high contour colors. Array length also limits how many contour levels are drawn on the map.
transitionDuration
Duration in milliseconds for the opacity cross-fade when contour tiles appear or disappear.
Set to 0 to disable the transition.
Top-level options
Property
Default
Description
language
Sets the initial UI language. It can also be changed later with mapalizer.configure().
Supported language code list: .
theme
Toolbar theme. Currently light and dark are supported.
verticalKey
CDN namespace used for toolbar assets, locale files, category metadata, and score data.
loadCss
Auto-load the distributed toolbar stylesheet. Set false if you want to host the CSS yourself. See CSS Customization.
The current default category definitions are available at
.
Key
Category
Key
Category
TRANSIT
Transit
ESSENTIALS
Essentials
HEALTH
Health
NATURE
Nature
DINING
Dining
SPORTS
Sports
SHOPPING
Shopping
CULTURE
Culture
Override Property
Type
Description
sortOrder
Number
Controls the category position in the toolbar. Lower values appear earlier.
icon
String
Custom SVG markup used instead of the default category icon.
weight
Number
Weight multiplier for the category. Higher values increase that category’s contribution to the final score. Set 0 to hide the category from the toolbar list.
isSelected
Boolean
Default selection state when the toolbar initializes.
These overrides let you shape the initial category experience without
changing the underlying built-in category set.
The live Configurator is the fastest way to experiment and
generate a production-ready configuration object.
auth
Controls session-token authentication for tile access.
Property
Type
Default
Description
siteToken
String
undefined
Publishable site token from portal.mapalizer.com. Required everywhere. Use mpl_pk_test_ on localhost and mpl_pk_live_ on real domains.
Authentication flow: On addToMap() Mapalizer posts your siteToken to the session API and receives a short-lived token. The toolbar DOM is only inserted after this request succeeds. Each tile request appends ?t=<token> to the URL (no CORS preflight). The token is automatically refreshed 60 s before expiry. On a 401/403 response Mapalizer silently refreshes once and retries; if the retry also fails, a mapalizer:autherror event is dispatched.
const result = await mapalizer.addToMap(map, {
auth: {
siteToken: 'mpl_pk_live_REPLACE_ME'
}
});
if (!result.ok) console.error('Mapalizer failed:', result.error, result.status);
Customising with CSS Custom Properties
Mapalizer exposes visual tokens on the .mpl root. Override those properties in
your own stylesheet to match your product brand without editing the distributed bundle.