Skip to main content

Viewer reference

product="viewer" shows a map published in Kaleidr Studio. The SDK replaces the contents of the mount target with an iframe that loads https://map-embed.kaleidr.com/embed/<id>. The map draws inside that iframe.

KeyNone. Do not pass one.
PlanEvery plan, Free included.
Renders inAn iframe from https://map-embed.kaleidr.com.
MeteringOne map load per view, charged to the map owner's organization.
CSPscript-src https://cdn.kaleidr.com and frame-src https://map-embed.kaleidr.com.

For a walkthrough, see Embed a published map.

Mount​

With the element:

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<kaleidr-map product="viewer" share-id="YOUR_MAP_ID"
style="display:block; height:480px"></kaleidr-map>

From JavaScript:

const handle = Kaleidr.mount('#map', {
product: 'viewer',
shareId: 'YOUR_MAP_ID',
});

With no SDK at all:

<iframe src="https://map-embed.kaleidr.com/embed/YOUR_MAP_ID"
width="100%" height="480" style="border:0;" loading="lazy"
referrerpolicy="no-referrer-when-downgrade" allow="geolocation; microphone; fullscreen; clipboard-write"
title="Kaleidr map"></iframe>

Chat bar​

layout="bar" turns the viewer into a chat bar: one question field for your page, with no map until a visitor asks. A question opens the published map, and the map's Kaleidr AI answers it there.

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<kaleidr-map product="viewer" share-id="YOUR_MAP_ID" layout="bar"
chat-title="Ask about the neighborhood"
prompts="Coffee within a short walk|Parks nearby"></kaleidr-map>

Answers open in one of two places:

SettingWhat a question does
No results-url (the default)The map opens over the page, filling the window, and asks the question. The visitor closes it with its close button. A later question asks the same map, so the conversation continues.
results-url="/map"The browser goes to that page with ?q=<question>. A viewer there with prompt-param="q" asks the question when the map opens, if the visitor came from a page of the same origin.

A results page:

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<kaleidr-map product="viewer" share-id="YOUR_MAP_ID" prompt-param="q"
style="display:block; height:600px"></kaleidr-map>
  • The map answers. The question goes to the map's own Ask Kaleidr panel, so the map needs Control Tower on (Studio, Kaleidr AI), and the rules of Kaleidr AI on a published map apply: the owner pays, and the map's allowed domains decide where it answers. On a map without Control Tower, the map opens and the question is not asked.
  • The bar loads no map. The map loads, and counts as a map load, when a visitor asks.
  • The bar draws in a shadow root of its own, so your page's CSS does not restyle it, and its styles need no style-src permission. It is as wide as the element and as tall as its content.
  • Its own labels follow lang, or the visitor's browser language when lang is not set: English, Spanish, French, German, Portuguese, Japanese, Korean, simplified and traditional Chinese, and Arabic. Your chat-title, placeholder and prompts are shown as you write them.
  • prompt pre-fills the field, and handle.send() asks from code. handle.send('Parks nearby') asks that question; handle.send() asks what is in the field.

The builder at template.kaleidr.com writes both snippets for a map you choose.

Options​

Mount optionAttributeTypeDefaultRequiredDescription
productproduct'viewer'noneyesSelects the viewer.
shareIdshare-idstringnoneyesThe id of the published map, from Studio's embed code. Must match ^[A-Za-z0-9._~-]{1,100}$.
mapIdmap-idstringnonenoAlias of shareId, used only when shareId is absent.
centercenter[longitude, latitude]; the attribute is "longitude,latitude"the saved viewnoOpening center.
zoomzoomnumberthe saved viewnoOpening zoom. Ignored at mount unless center is also given.
pitchpitchnumber, degreesthe saved viewnoOpening tilt.
bearingbearingnumber, degreesthe saved viewnoOpening rotation.
viewerBaseviewer-baseURLhttps://map-embed.kaleidr.comnoOrigin the iframe loads from. Only the origin is used. You do not need this in production.
basebaseURLhttps://cdn.kaleidr.comnoOrigin the SDK loads viewer.js from. Only the origin is used, and only the origins listed under The base override are honored.
enabledflagbooleannonenoPer-mount arm of the enable gate.
promptpromptstringnonenoA question to put to the map's Kaleidr AI when the map opens. On a chat bar, the field's pre-filled text. At most 500 characters.
promptParamprompt-paramstringnonenoReads prompt from this query parameter of the page's own URL: q on a chat bar's results page. Read only when the visitor came from a page of the same origin, so a link from elsewhere cannot make your map ask anything.
layoutlayout'map' or 'bar''map'nobar mounts the chat bar.
promptspromptsarray of strings; the attribute separates them with |nonenoChat bar: example questions, shown as buttons that ask them.
titlechat-titlestringnonenoChat bar: the label above the field.
placeholderplaceholderstring"Ask about this map", in the bar's languagenoChat bar: the field's placeholder.
accentaccentCSS color#2da84anoChat bar: the color of the send button, the icon and the focus ring.
themetheme'light', 'dark' or 'auto''light'noChat bar: its colors. auto follows the visitor's system setting.
langlanglanguage tagthe visitor's browser languagenoChat bar: the language of its own labels.
resultsUrlresults-urlURLnonenoChat bar: sends visitors to this page with ?q=<question> instead of opening the map over the page.

publishableKey, styleId, map, mapTarget and contained have no effect on a viewer mount. A key is worse than useless here: the SDK exchanges it for a session the viewer never uses, and if that exchange is refused the map does not render.

The id​

shareId accepts either kind of id that Studio produces for a map:

  • The published map's id. It is the id in the snippet on the Publish & embed page and in the Share dialog's Embed tab; the two show the same id.
  • A share link's id. It is the 16-character id at the end of the URL on the Share dialog's Link Share tab.

The published map's id shows the map as it is currently saved. A share link's id shows the snapshot taken when that link was created. Kaleidr AI accepts either id: on a share link it follows the snapshot's Kaleidr AI switches, while the map is published and on the map's current allowed domains; see Chat on a published map.

An empty or malformed id does not throw. The SDK logs

[kaleidr:viewer] Kaleidr map: invalid id "" — must match ^[A-Za-z0-9._~-]{1,100}$.

and nothing renders. Kaleidr.mount still returns a handle, whose methods do nothing.

Plain iframe URL​

https://map-embed.kaleidr.com/embed/<id>?camera=<lon>,<lat>[,<zoom>]&pitch=<deg>&bearing=<deg>&q=<question>
Query parameterValueEffect
cameralongitude,latitude or longitude,latitude,zoomOpening center and, optionally, zoom.
pitchnumber, degreesOpening tilt.
bearingnumber, degreesOpening rotation.
qtext, at most 500 charactersA question to put to the map's Kaleidr AI when the map opens. Asked only when the viewer is embedded in a page, and ignored on a map without Control Tower.

The SDK builds the same URL from its camera options and prompt.

Camera​

The opening camera is assembled from these sources. A later source replaces only the fields it provides.

  1. The basemap's default view.
  2. The view the author saved in Studio. An author can save a separate view for desktop, tablet and phone widths, in which case the map uses the one that matches the width of the frame. An author can instead set the map to frame its content, in which case the map fits that content to the frame.
  3. The camera you pass (center, zoom, pitch, bearing as options or attributes, or camera, pitch and bearing in a plain iframe URL).

A camera your page passes wins over the author's view, including a view saved for the visitor's screen width and content framing. The fields you do not pass keep the author's values.

A map with per-width views or content framing frames itself again when the frame is resized, until the visitor moves the map. A camera from your page ends that too: after a camera passed at load, or a setCamera call, the map no longer re-frames itself on resize. setCamera changes only the fields you give it and leaves the others as they are.

center is longitude first: [-0.1276, 51.5072] is London.

Sizing​

  • The iframe is 100% of the mount target's width, has no border, and has rounded corners.
  • Its height is 100% of the target when the target has a height at mount time. Otherwise it is a fixed 500 pixels.
  • The mount replaces the target's children and sets position:relative (if the target has no inline position) and overflow:hidden on it.
  • <kaleidr-map> is display:block by default, so a height on it applies. Give it a height. The snippets also write display:block, which covers Safari before 16.4, where the element stays inline.

Handle​

Kaleidr.mount returns the handle synchronously. See the handle matrix for every product.

MemberOn viewer
handle.product'viewer'
handle.setCamera(camera)Moves the map.
handle.setTheme(theme)Not supported. Logs a warning and does nothing.
handle.setStyle(style)Not supported. Logs a warning and does nothing.
handle.send(text)Asks the map's Kaleidr AI, as if the visitor typed text. On a chat bar, send() with no text asks what is in the field. A question sent while one is being answered waits for it, and a newer one replaces any still waiting.
handle.destroy()Removes the iframe and stops listening.

setCamera(camera)​

handle.setCamera({
center: [2.3522, 48.8566], // [longitude, latitude]
zoom: 12,
pitch: 45,
bearing: -20,
duration: 800, // milliseconds
});
FieldTypeDescription
center[number, number]Longitude, latitude.
zoomnumberZoom level. Unlike at mount, zoom works without center here.
pitchnumberTilt in degrees.
bearingnumberRotation in degrees.
durationnumberAnimation length in milliseconds. Omitted or 0 jumps with no animation.

All fields are optional. Fields you leave out keep their current value.

You can call setCamera at any time after Kaleidr.mount returns, including on the next line. A call made before the map inside the iframe is ready is kept and applied, in order, when the map reports ready. The latest 256 calls are kept. If the map has not reported ready after a bounded wait, normally 10 seconds after the frame loads, the kept calls are sent anyway, with one console warning. You do not need to wait for the kaleidr-embed:ready message first. For the view the map opens on, mount options are still the direct way: the map starts there instead of moving there.

There is no method that reads the camera back.

Element attributes after mount​

On a mounted <kaleidr-map product="viewer">, changing center, zoom, pitch or bearing moves the map with no animation. Changing share-id or any other attribute does nothing. To show a different map, remove the element and insert a new one.

Messages from the iframe​

The iframe posts messages to the embedding page. Two of them are the public signal for "loaded" and "failed":

// The map drew for the first time.
{ type: 'kaleidr-embed:ready', id: string, source: 'publish' | 'share' }

// The map could not load, or part of it failed to draw.
{ type: 'kaleidr-embed:error', id: string | null, code: string, message: string }
window.addEventListener('message', (event) => {
if (event.origin !== 'https://map-embed.kaleidr.com') return;
if (event.source !== iframe.contentWindow) return; // which embed sent it
const msg = event.data;
if (msg?.type === 'kaleidr-embed:ready') onReady(msg);
if (msg?.type === 'kaleidr-embed:error') onError(msg);
});

With the SDK, iframe is the first <iframe> inside the mount target: target.querySelector('iframe').

Error codes​

codeTerminalMeaning
no_idyesThe iframe URL carries no map id. id is null.
not_foundyesNo published map or share link has this id: the map was never published or was unpublished, the share link's map was deleted or Kaleidr removed the link, or the id is mistyped.
domain_not_allowedyesThe map has an allowed-domain list and the embedding page's domain is not on it, or the page sent no referrer.
map_loads_exhaustedyesThe owner's organization has used its map loads for the period.
fetch_failedyesThe map could not be fetched.
maplibre_errornoThe map started, but something failed to draw. May arrive more than once, before or after ready.

After a terminal code, the frame shows a short message in place of the map and ready is not sent.

Rules​

  • ready is sent once per load, after the map has drawn and the view has been counted.
  • The SDK creates the iframe with loading="lazy", so neither message arrives until the frame comes near the viewport.
  • The frame posts other messages whose type starts with kaleidr-embed:. The SDK uses them to connect a chat panel to the map. They are not a public contract and can change. Do not build on them.
  • The frame acts on control messages, such as the camera move behind setCamera, only when they come from the page that directly embeds it. A message posted to the frame from any other window or frame is ignored, so call setCamera from the page that holds the iframe.
  • The SDK and the element emit no DOM events and offer no ready promise.

Messages the visitor can see​

These appear inside the frame, in place of the map:

TextCode
"Loading map…"none: the map is loading
"Couldn't find a map id in the URL."no_id
"This map isn't available — it may have been unpublished, paused, or the link is incorrect."not_found
"This map isn't allowed to render on this site. Please contact the map owner."domain_not_allowed
"This map has reached its map load limit. It will be available again when the owner's allowance resets."map_loads_exhausted
"Could not load the map. Please try again in a moment."fetch_failed
"Unexpected error loading the map."none: an unexpected failure during startup

Uploaded data​

A published map draws the datasets and image overlays its author added in Studio's Data panel. The frame loads them itself; no option, attribute or key is involved, and the data never passes through your page.

BehaviorDetail
What is shownEvery dataset and image overlay the published map includes, as the layer its author styled.
Who can read itAnyone who can open the map. Allowed domains do not make the data confidential.
What a visitor's browser receivesEach dataset whole, with all of its columns. A large dataset takes longer to appear.
A dataset that cannot be loadedThe rest of the map draws, without that layer.
Deleting a dataset in Studio's Data panelThe dataset is deleted and no longer served, on the published map and on every share link that drew it. A browser that already loaded it keeps it, and a download link already issued can stay readable for up to one hour.
Unpublishing the mapNothing of the map is served through its published id, its datasets included. The frame shows the not_found message. Publishing again restores the same id.
Share linksA share link is a snapshot of the map's design when the link was created. It keeps showing its map after the map is unpublished, without Kaleidr AI until the map is published again. Studio has no control to delete or pause one: it keeps working until its map is deleted or Kaleidr removes the link at the owner's request. See Share links.

Uploaded data on a published map covers each of these.

Allowed domains​

The map's owner can limit the sites a map renders on, in Studio under Share, Embed, Specific domains.

  • A listed domain covers its subdomains.
  • The check compares the list with the host name of the referrer the browser sends for the iframe. A missing referrer fails the check.
  • A failed check shows the "isn't allowed" message and posts domain_not_allowed.
  • A view that fails the check is not counted as a map load.

Metering​

  • A view counts one map load against the organization that owns the map.
  • The same visitor viewing the same map again within 24 hours is not counted again.
  • Views on Kaleidr's own sites are not counted.
  • When the allowance is used up, the frame shows the limit message until the allowance resets. See Quota and rate limits.

Console messages​

MessageMeaning
[kaleidr] <kaleidr-map> requires product="chat|viewer|editor|tile"The element has no valid product. Nothing mounts.
[kaleidr:viewer] Kaleidr map: invalid id "…" — must match ^[A-Za-z0-9._~-]{1,100}$.The id is empty or malformed.
[kaleidr:viewer] mount target not found: <selector>Kaleidr.mount found no element for the selector.
[kaleidr:viewer] [kaleidr] failed to load https://cdn.kaleidr.com/embed/v1/viewer.jsThe viewer bundle could not load: a network failure, an ad blocker, or a script-src policy.
[kaleidr] setStyle() is not supported on product "viewer" — the call is a no-op. …You called a handle method the viewer does not have.

Not available​

  • Events for clicks, camera moves or selections.
  • Reading the camera, the layers or the data of the map.
  • Adding your own markers or layers to the embedded map.
  • Changing the basemap or theme from the embed.