Deep links
Some places can show an iframe but cannot run your JavaScript: a SharePoint page, a Confluence macro, a link in an email. For those, the map's URL can carry the state it should open in. No SDK is involved.
<iframe src="https://embed.iconmap.ai/v/pub_...?bookmark=bm-north&f.region=EMEA&lang=de"
style="width: 100%; height: 600px; border: 0"></iframe>
What a link can carry
| In the URL | Does |
|---|---|
?bookmark=<id> |
Opens on one of the author's bookmarks |
?f.<name>=<value> |
Sets a declared filter. Repeat for several filters |
?lang=<code> |
Reader language, for example fr or de-DE |
#s=<scene> |
Restores a whole captured scene: camera, visibility, slicers, filters, selection, basemap |
When several are present they are applied in that order, so a scene has the last word.
Filter values
A plain value is taken as text. Anything else is written as JSON and URL-encoded:
?f.region=EMEA
?f.region=%5B%22EMEA%22%2C%22APAC%22%5D ["EMEA","APAC"]
?f.period=%7B%22operator%22%3A%22inLast%22%2C%22count%22%3A30%2C%22unit%22%3A%22days%22%7D
A name the author did not declare is ignored, exactly as it would be rejected through the API - a link can never filter on a column the author did not offer.
Why the scene is in the fragment
Everything after # stays in the browser: it is not sent to the server, so it never appears in access logs, proxies or analytics. A scene can hold a selection and filter values, which is reason enough to keep it out of them.
Building links
From the Publish dialog
After publishing, the dialog offers Copy link to this view next to the embed URL. It captures the editor's current camera, layer visibility and slicer selections as a scene and copies a link that opens the published map exactly there.
From your page
const { sceneToUrl } = IconMapEmbed;
const scene = await map.captureScene();
const link = sceneToUrl("https://embed.iconmap.ai/v/pub_...", {
scene,
bookmarkId: "bm-north",
filters: { region: ["EMEA"] },
language: "de",
});
Every part is optional. deepLinkFromUrl(url) is the inverse, if you want to read one back:
const { deepLinkFromUrl } = IconMapEmbed;
const { scene, bookmarkId, filters, language } = deepLinkFromUrl(location.href);
By hand
A scene is base64url-encoded JSON, so a link can be produced by anything that can do that - a server, a report, a script:
const scene = { v: 1, camera: { center: [-3.18, 51.48], zoom: 12, bearing: 0, pitch: 0 } };
const s = btoa(JSON.stringify(scene)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
const link = `https://embed.iconmap.ai/v/pub_...#s=${s}`;
v and camera are required; everything else in a scene is optional.
Good to know
- Links survive a re-publish of the same layers. Ids the map no longer has are skipped; the rest applies. A re-publish does mint a new publish id, so links to the old publish keep opening the old one until the author revokes it.
- A deep link needs no allowed origin. Allowed origins govern who may drive a map from script. A link only sets the state the map opens in, using things any reader could do by hand.
- Length. A scene with a large selection makes a long URL. Browsers cope with several thousand characters, but some chat and email tools truncate. Capture only what you need:
captureScene({ include: ["camera", "visibility"] }). - With the SDK too. If your page uses the SDK, prefer the
scene,bookmarkId,filtersandlanguageoptions - they do the same thing and are typed.