Get started

Mount the studio props

The generated props of every element on Mount the studio. The guide is where they are explained; this is the whole surface.

MountayaStudio

mapClient

MountayaMapOptions["client"]

The client the map draws through.

Omitted, it is the HOST's client, which is the right answer wherever one credential serves both the reads and the tiles. State it where the map's does not match (a signed-in studio that rides a session cookie for tiles and a key for everything else), and the two halves stay independent.

Whichever client ends up here is also what the tile transform is DERIVED from: its browser-safe credential, its tile-API origin, its language. That is why the two are separate props rather than one seam and why neither is required: see transformRequest below.

Its credential is held to the host's rule: under a host rendering the Embedded Studio (the default), a publishable key given no session token, and a session token minted for another surface than studio-embedded, are refused with a configuration error before the map draws a tile; a share token and the browser's own session are taken, and under a host declaring data.surface: "embedding" (Mountaya's hosted embed) a key with any session, or none, is accepted. While its session's first token is on its way, the map is not built, so none of its requests goes out without the token; the host waits the same way for its own client only.

transformRequest

TileRequestTransform

Overrides the transform that stamps a credential onto each tile request.

Omitted, the map derives one from whichever client is drawing it: its browser-safe credential, its tile-API origin as the ONLY host allowed to receive that credential, and its language. That derivation is narrower than anything a caller would write by hand: it follows a client repointed at a local stack or a proxy, where a hand-written origin would keep naming the public host and silently authenticate nothing.

Supply one for what the credential projection cannot know: a share token scoped to a single path prefix, a surface=published opt-in, an origin the client does not speak to. createTransformRequest from @mountaya/elements builds it, and takes scoped and next for exactly those cases.

A secret-key client projects no credential at all, so the derived default authenticates as nobody rather than putting a server-side key on a map.

demTilesUrl

string

The terrain tiles the base map bakes its relief from, as a TileJSON or XYZ template.

A URL rather than a provider, because every DEM source this speaks to is one of those two, and which one serves elevation (under whose key) is the host's answer.

The answers, most explicit first: this prop, then the host's assets.demUrl, then the layers manifest's own elevation. Set none of them and the map renders flat rather than firing a request that cannot succeed.

config

StudioConfig

Which controls the studio offers, and which terrains and overlays it may show.

It is a prop rather than something the studio resolves because both halves of the resolution are the host's: whose stored defaults apply, and which terrains and overlays their viewers are offered. Spread the default and narrow what you mean to narrow.

preserveDrawingBuffer

boolean

Whether the map's WebGL context preserves its drawing buffer.

Keep it off unless something reads the canvas out of band (a session recorder, a screenshot service): preserving the buffer costs a copy per frame on every pan.

constraints

StudioConstraintResolver

The camera's limits: a zoom floor and ceiling, and a boundary it may not leave.

A RESOLVER rather than a value, so the host keeps which organization is authoritative and how a geofence is spelled on its wire. Omitted, the camera is unconstrained.

url

StudioUrlSeam

The slice of the host's URL the studio mirrors its map state into, and restores it from on mount.

Two answers, most explicit first: this prop, then the host's behavior.url, the seam the verbs write through. A host that states the seam on MountayaStudioHost states it once. With neither, the studio still works and does not survive a reload: the terrain, the overlay, the enrichments and the time offset are held in the store alone.

collabEngine

CollabEngine | null

The live collaboration session for the open itinerary.

Separate from the zone's, because the two resources are edited through different tools and a reader can hold a lock on one while another holds the other. Omitted, the editor works exactly as it does for a single author.

zoneCollabEngine

CollabEngine | null

The live collaboration session for the open zone.

The zone half of the pair above, and independent of it for the same reason. Omitted, zone editing works exactly as it does for a single author.

googleMapsApiKey

string

The Google Maps key the Street View surfaces probe coverage and open a panorama with.

Omitted, the pegman and the context menu's Street View action are not offered, which is the honest absence: a control that opens nothing is worse than one that is not there.

streetViewHandle

ReactNode

The draggable handle a reader drops onto the map to open Street View.

elevationPanel

(collapsed: boolean) => ReactNode

The elevation panel, drawn inside the studio's own docked sheet.

A render prop rather than a node, because the sheet resolves how much room the panel has from the live geometry around it (an open floating panel collapses the profile to its stat bar), and that answer is the studio's to make and the panel's to obey.

modals

ReactNode

The host's own portalled surfaces, mounted inside the studio's element context so they read the same glyphs, copy and map.

Rendered unconditionally: whether a wizard's chunk is loaded is the host's decision, and every one of these gates on a store slot the host can read through useUiStore.

MountayaStudioViewer

embedConfig

EmbedConfig

required

What the viewer is showing, fully resolved: the itinerary or collection, the terrain and overlay it opens on, which controls and profile sections it offers, and the reader's language. The host resolves it (from a publishable key, a URL, its own stored defaults, or all three), and this surface derives the control config and seeds the display state from it through the bus.

mapClient

MountayaMapOptions["client"]

required

The client the map draws through, which the tile transform is derived from unless transformRequest states one.

Both must authenticate as the SAME audience. The point of a viewer is that what a publisher previews is what a visitor gets, and a client reading as the owner behind a transform reading as a visitor breaks exactly that, silently, because each half works.

Its credential is held to the host's rule: under a host rendering the Embedded Studio (the default), a publishable key given no session token, and a session token minted for another surface than studio-embedded, are refused with a configuration error before the map draws a tile; a share token and the browser's own session are taken, and under a host declaring data.surface: "embedding" (Mountaya's hosted embed) a key with any session, or none, is accepted. While its session's first token is on its way, the viewer shows its cover alone: no map is built, no read is made and no ready event is posted until the token lands, so none of its requests goes out without the token, and the ready deadline counts from then.

safetyRules

EmbedSafetyRules

The security boundary a runtime override is re-clamped to.

A viewer inside an iframe accepts configuration from the page around it, so it folds those overrides over embedConfig and clamps the result to the SAME rules the host applied when it resolved the config. Omitted, no override is accepted, which is the right answer for a surface nobody outside can reconfigure.

publishedSurface

boolean

Read the PUBLISHED snapshot rather than whatever the credential would otherwise resolve to.

A visitor's credential already selects the publication, so a real viewer leaves this off. A PREVIEW does not: it authenticates as the owner in order to open at all, and would otherwise read the editor's draft. It must move in lockstep with the tile transform's option of the same name: one without the other paints draft geometry under a published elevation profile, or the reverse.

It also selects the snapshot a collection's specification is read for, whose extent a collection embed opens on. That read goes through the client rather than the transform, so this is what keeps the extent on the itineraries the tiles draw. The docked profile is handed the same snapshot as its surface option, so the reader's pace re-times the published route.

studioConfig

StudioConfig

Override which controls the surface offers.

Omitted, they are derived from embedConfig: the publisher's own toggles, which is what a third-party embed should honour. A first-party surface passes its own resolved config instead, so a shared view offers what that host offers rather than what an arbitrary publisher enabled.

transformRequest

TileRequestTransform

Override the transform that stamps a credential onto each tile request.

Omitted, the map derives one from the client drawing it: MountayaStudioProps documents the derivation and when a surface has to state its own.

watermark

ReactNode

A mark drawn over the map, for a surface that carries attribution.

A NODE rather than a flag, because whose mark it is and what it says are the host's, and a package shipping a brand would be shipping the wrong one. It is not the tile credits: those are a licence obligation the map draws itself, on every surface, always.

cover

(visible: boolean) => ReactNode

The cold-load cover, told whether it should still be showing.

A render prop because the studio owns the TIMING (the cover comes down when the constraints hook reports the initial view framed, with a timeout backstop), and the host owns what is drawn until then. Without one the map's default centre is visible for the moment before the framing lands.

tilesRequiredOverlay

ReactNode

What to draw over the map while the API refuses its tiles (a 401, a 402 or a 403).

A page served to visitors passes a neutral state that names nothing to do, as a share link and an embed do; a signed-in host may pass its own sign-in. Omitted, the map stays empty.

elevationPanel

(options: ViewerProfileOptions) => ReactNode

The docked elevation profile, drawn inside the viewer's own sheet.

A render prop rather than a node: which sections it shows comes from the config, and how much room it has is resolved from the live geometry around it, so both are the studio's to decide and the panel's to obey.

streetViewHandle

ReactNode

The draggable handle a reader drops onto the map to open Street View.

googleMapsApiKey

string

The Google Maps key the Street View surfaces probe coverage and open a panorama with.

modals

ReactNode

The host's own portalled surfaces, mounted inside the viewer's element context so they read the same glyphs, copy and map. Rendered unconditionally: whether a chunk is loaded is the host's decision, and each of these gates on a store slot it can read.

demTilesUrl

string

The terrain tiles the relief is baked from.

The answers, most explicit first: this prop, then the host's assets.demUrl, then the layers manifest's own elevation. Set none of them and the map renders flat rather than firing a request that cannot succeed.

preserveDrawingBuffer

boolean

Whether the map's WebGL context preserves its drawing buffer: off unless something samples the canvas out of band, because it costs a copy per frame on every pan.

zoomRange

EmbedZoomRange

required

The zoom floor and ceiling the viewer locks its camera to.

REQUIRED, while both ends of it are optional, and the pair is deliberate: how far into a published view a reader may zoom is the publisher's answer and never this package's, so a host states it, and {} is how a host states that there is no clamp. An optional prop would let a surface reach a reader without anyone having decided.

MountayaStudioHost

assets

StudioAssetsConfig

Where the pictures come from: the glyph tables, the relief raster, the activity and layer thumbnails and the routing guide's pictures.

appearance

StudioHostAppearanceConfig

What it looks like: the scheme, the density, the tokens, the theme, the canvas paint.

behavior

StudioHostBehaviorConfig

What it does, and what you do instead: handlers, seams, confirm, notify, the routers.

children

ReactNode

required

What the studio mounts inside every provider it wires: a MountayaStudio, a MountayaStudioViewer, or surfaces you have arranged yourself.

client

Mountaya

The client every read and write beneath this host runs on.

Top-level rather than in data, because it is the one thing a studio cannot be mounted without and the first thing a consumer types. Omitted, the host reads the MountayaProvider above it and throws if there is none: a missing credential is a configuration error, not a studio that renders empty.

data

StudioHostDataConfig

What the studio is showing, and to whom: the catalog, the grants, the store, the viewer.

i18n

StudioI18nConfig

Which words, and which regional conventions: the language, the locale, both bundles.

itineraryId

string | null

The itinerary the studio opens, null to clear it, omitted to leave activation to a surface below.

Top-level beside client for the same reason: it is the other half of the shortest useful call, and a studio with a credential and no itinerary is a studio waiting for one.

plugins

StudioPluginsConfig

What a third party ADDS to it: the plugins to install, where a failure goes, the engine.

StudioHostRegistryProvider

children

ReactNode

required

The surfaces that register into the registry.

registry

StudioHostRegistry

required

The registry the surfaces beneath read and register into, in place of a host's.

ShareViewModal

name

string

required
opened

boolean

required
shareToken

string

required
target

ShareLinkTarget

required
strings

ShareViewModalStrings

Overrides the words this surface says, for this surface only.

Folded onto whatever the provider resolved, so an override naming one key leaves the rest of the section alone, and carried down to the rows and pickers this surface mounts. Scoped to the sections it renders: a key it never says is a type error rather than a silent no-op.

Handlers

An on* handler suppresses the element's own default. Left unset, the element acts; set, it becomes presentational and your handler decides. The two never both fire.

MountayaStudioViewer

onReady

(payload: Omit<ReadyMessage, "type">) => void

onReady fires each time the initial view settles, on a cold load and again on every content switch, carrying what an iframe host needs to size and identify what it is showing. A viewer mounted inside an iframe posts it to the parent page; one rendered on a page of its own omits it, because there is nobody to notify. One that throws stops nothing: the view has settled and the cover has lifted by then, and its fault is raised on a microtask, where the page's own error handling sees it.

ShareViewModal

onClose

() => void

required