Embedding & Sharing
The Meratyn web viewer can be embedded in any web page and configured through URL query parameters. This is how you turn a shared project into a live, focused map for a website, a report, or a dashboard.
The live viewer
The live viewer runs at https://mappview.mapptech.com.co. The examples below use that origin. It runs entirely in your browser: it has no analytics and no server account, and the data you load is processed client-side. Network requests occur when you add a remote URL, explicitly share a project, or send a prompt to a configured AI provider or managed proxy.
Open a public project by passing its .meratyn.json URL with the url parameter:
https://mappview.mapptech.com.co/?url=https://example.com/project.mappview.json
A project URL like this comes from Project → Share. See Projects.
A chrome-free maponly embed shows only the map, as in this shared 3D Tiles project:
URL parameters
| Parameter | Example | Description |
|---|---|---|
url | url=https://example.com/project.mappview.json | Loads a .meratyn.json project from a public URL. |
layout | layout=compact | Compact embed layout: icon-only toolbar buttons and hidden project metadata. embed and iframe are aliases. |
toolbar | toolbar=icons | Icon-only toolbar buttons without the full compact layout. icon and icon-only are aliases. Use none to hide only the top toolbar while retaining panels and the status bar; hidden, hide, and off are aliases. |
panels | panels=collapsed | Starts the Layers and Style panels collapsed while keeping their icon rails reachable. Use none to hide all panels; hidden, hide, and off are aliases. |
hidePanels | hidePanels=true | Alternative way to hide those panels. |
maponly | maponly | Hides all chrome (toolbar, panels, and status bar), leaving only the map. The bare flag or true, 1, yes, on enable it. |
welcome | welcome=0 | Hides the first-launch welcome wizard. Accepts 0, false, off, or no. A url= deep link already suppresses it automatically. |
theme | theme=dark | Sets the initial color theme, overriding the OS preference. Accepts dark or light; the in-app toggle still works afterward. |
tool | tool=adaptive_filter | Opens the Processing → Whitebox Toolbox dialog on a specific tool by its id. Unknown ids open the dialog without preselecting a tool. |
data | data=https://example.com/roads.geojson | Loads a public GeoJSON, ZIP, GeoParquet, COG, or PMTiles URL. Repeat data to load several layers. |
style | style=https://example.com/roads-style.json | Applies a Mapbox style to the matching data entry. Styles are positional, so use an empty value (style=) to skip one. |
settingsUrl | settingsUrl=https://example.com/viewer.json | Loads an ephemeral presentation settings document (layout, theme, interface, and language). settingUrl is an accepted spelling; credentials and project paths are ignored. |
Parameters combine. For a narrow, chrome-free, dark embed of a shared project:
https://mappview.mapptech.com.co/?url=https://example.com/project.mappview.json&maponly&theme=dark
Use panels=collapsed when the map should lead the presentation without
removing access to the side panels. Both Layers and Style start closed on their
icon rails; selecting a rail icon expands that panel when needed. This differs
from panels=none (or its aliases), which removes the side-panel rails
entirely.
Loading data and styles from a URL
data accepts HTTP(S) URLs ending in .geojson, .json, .zip,
.parquet/.geoparquet, .tif/.tiff/.cog, or .pmtiles. A GeoJSON or ZIP
is decoded in the browser; GeoParquet uses the DuckDB-WASM reader and raster
formats use the raster plugin. The loader rejects malformed URLs and bounds
downloads before buffering them. When several data values are present,
matching style values are applied in order and one map fit runs after the
batch completes. A failed item rolls back the layers created by that batch.
For a presentation-only viewer, settingsUrl (or settingUrl) points at a
JSON object containing language, layout, theme, and uiProfile. The
document is fetched with a short timeout and is never written to local
preferences; sensitive fields such as API tokens, plugin manifests, startup
paths, and credentials are discarded. A valid locale/lang query parameter
still takes precedence over the document’s language.
Deep-linking a Processing tool
tool=<id> opens the Processing → Whitebox Toolbox dialog preselected to a tool.
Any additional query parameters pre-fill that tool’s form, using the tool’s
own parameter names, so a link can arrive ready to run:
https://mappview.mapptech.com.co/?tool=extract_cog_subset&url=https%3A%2F%2Fexample.com%2Fdem.tif&bbox_crs=4326
When tool= is present the app is in tool mode: url names a tool input
(here, the COG to subset) rather than a project to load, so the project loader
stands down. App/embed parameters above (theme, layout, panels, maponly,
locale, …) keep their own meaning and are never passed to the tool.
Preselection and parameter prefilling apply only to an id that matches the
Processing menu: an id not in the menu still opens the dialog, but without
preselecting a tool or applying any parameters. A known id the current engine
doesn’t expose (WASM in the browser, the Python sidecar on desktop) likewise
isn’t preselected. Tool ids match the Processing menu — the same ids used across
the Whitebox toolbox.
Embedding in a page
Drop the viewer into an <iframe>:
<iframe
src="https://mappview.mapptech.com.co/?url=https://example.com/project.mappview.json&maponly"
title="Meratyn map"
width="100%"
height="600"
style="border: 0;"
loading="lazy"
allow="fullscreen; geolocation"
></iframe>
Use layout=compact when you want a slim toolbar to remain (for example, so viewers can switch basemaps), or maponly for a pure map.
Talking to the map at runtime
URL parameters configure the app once, at load. To keep talking to a live
embed (fly to the record the user just clicked in your app, highlight it, open a
processing tool) and to hear what the user does inside the map, use the embed
postMessage API.
Enabling it
The API is off by default: a public deployment can never be driven by the
page that frames it. It is enabled by allowlisting the origins you trust in the
deployment’s configuration (for example, https://portal.example.com for your
portal). If messages never arrive or are ignored, ask whoever operates your
Meratyn deployment to add your page’s origin to the embed allowlist.
Entries are origins (scheme://host[:port]); a trailing path is ignored. *
allows any origin and is only appropriate on a private network. The allowlist is
enforced in both directions: a message from an unlisted origin is ignored, and
every message the app sends is addressed to a listed origin.
Setting the allowlist also narrows the ?embed=1 project/scripting bridges (used
by the Python package) to the same origins.
Message shape
Every message, in both directions, is versioned:
{ "v": 1, "type": "setView", "payload": { "center": [-95.7, 37.1], "zoom": 5 } }
Messages the app sends also carry "source": "mappview", so you can filter
them out of the other postMessage traffic on your page.
Host to Meratyn
| Type | Payload | Effect |
|---|---|---|
loadProject | { url } | Loads a .meratyn.json project without reloading the iframe. |
setView | { bbox } or { center, zoom, bearing, pitch, duration } | Fits a bounding box, or flies the camera to the properties you send. |
highlightFeature | { layerId, featureId | featureIds | filter, fit } | Selects and highlights features; filter matches properties. fit zooms to them. |
openTool | { id, params } | Opens the Processing dialog on a tool, pre-filling params. Runtime twin of ?tool=. |
addData | { url, styleUrl, fit } | Adds one public HTTP(S) GeoJSON, ZIP, GeoParquet, COG, or PMTiles source through the same document commands as Add Data. styleUrl is optional and fit defaults to true. |
Send { layerId } alone to highlightFeature to clear the highlight. A request
that names features (or a filter) but matches none is rejected rather than
treated as a clear, so a mistyped id does not silently wipe the user’s selection.
Highlighting reads the layer’s features from the project, so it applies to vector
layers Meratyn holds as GeoJSON, not to ones whose features live only in a tile
source.
Add a requestId to any message and the app answers with an ack (below)
reporting whether it worked.
addData is remote-only: an iframe cannot read a host page’s local files, so
file: and relative paths are rejected. Imports run in host-message order. If
an import fails or the iframe closes, Meratyn cancels the remote work and
removes every layer created by that request; the acknowledgement exposes a
generic failure without echoing a private URL.
Meratyn to host
| Type | Payload | Fires when |
|---|---|---|
ready | { version } | The app has mounted and is listening. |
ack | { requestId, ok, error } | A message you sent with a requestId was applied (or rejected). |
projectLoaded | { url, name, layerIds } | A project finished loading, whoever started it. |
selectionChanged | { layerId, featureIds } | The user (or your highlightFeature) changed the selection. |
viewChanged | { bbox, center, zoom, bearing, pitch } | The camera moved (throttled to about four events a second). |
toolCompleted | { id, name, status, engine, durationMs, outputLayerNames } | A processing run finished, successfully or not. |
serverFileWritten | { path, toolId } | A file-based tool wrote an output (conversion and raster tools). |
A host page
<iframe
id="map"
src="https://mappview.mapptech.com.co/?url=https://erp.example.com/fields.mappview.json&maponly"
title="Meratyn map"
width="100%"
height="600"
style="border: 0"
></iframe>
<script>
const frame = document.getElementById("map");
const APP_ORIGIN = "https://mappview.mapptech.com.co";
const send = (type, payload) =>
frame.contentWindow.postMessage({ v: 1, type, payload }, APP_ORIGIN);
window.addEventListener("message", (event) => {
if (event.origin !== APP_ORIGIN) return;
const message = event.data;
if (message?.source !== "mappview" || message.v !== 1) return;
if (message.type === "ready") {
// Safe to start sending commands.
} else if (message.type === "selectionChanged") {
showRecordFor(message.payload.featureIds[0]);
}
});
// Click a record in your own UI: fly to it and highlight it, no reload.
function focusField(field) {
send("setView", { bbox: field.bbox });
send("highlightFeature", {
layerId: "fields",
filter: { parcel_id: field.id },
fit: true,
});
}
function addRoads() {
send("addData", {
url: "https://data.example.com/roads.geojson",
fit: false,
});
}
</script>
Wait for ready before sending: messages that arrive before the app has mounted
are not queued. Treat ready as idempotent, since it is re-sent whenever the app
remounts (a navigation inside the frame, a development hot reload).
What works in an embed
The viewer supports map navigation, browser-selected and URL-based data, styling, the SQL Workspace, browser-capable processing, and most plugins in an embed. Browser project files can be opened or saved when the embedding layout exposes those commands, and hosts can use the project APIs. Native filesystem dialogs and remembered paths, local MBTiles and raster reads, and sidecar-only processing still require the installed app.
See the Sharing & Embedding tutorial for a full walkthrough.