Files
GeoLibre/docs/tutorials/sharing-embedding.md
T
d165d4da06 feat(embed): let a layout=viewer embed opt into drawing (#3154)
* feat(embed): let a layout=viewer embed opt into drawing

`layout=viewer` deactivates the geometry editor, so a host page that embeds
the read-only viewer cannot let the user draw, even though getDrawnFeatures
and featuresChanged (#3021) can read a drawing back.

Add a `draw` URL flag. With `?layout=viewer&draw` the geometry editor is
let through (`isViewerBlockedPlugin`), so `?plugin=geo-editor` or a project
that lists it can open its toolbar. Annotations and GeoAgent stay blocked.
The flag only takes effect when the deployment grants `project:edit`, and
without it nothing changes. `draw` is reserved so it never becomes a tool
parameter in a `?tool=` link.

The viewer also stops offering ways to edit or move data around the
deployment's capability gates: Identify no longer shows Edit geometry or
Edit attributes (this was already reachable in `layout=viewer` before this
change), and the editor toolbar drops its Open/Save file buttons.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(embed): set viewer file-tools flag during render, document drawing readback needs

The geometry editor reads its file-tools flag once at construction, and the
plugin restore and ?plugin= deep link construct it from effects. Setting the
flag from an effect in the guard hook could lose that race against a child's
effect, so set it while rendering, which precedes every effect. Add a render
test for it and record why an empty fileModes list is safe upstream.

Docs: reading drawings back needs the embed allowlist and the export:data
capability, not only project:edit; use a self-hosted placeholder URL in the
drawing example.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Address review feedback

- Move the viewer gate on Identify's edit actions into
  useIdentifyEditActions and pass usePluginDeepLink the layout options
  instead of two booleans, so DesktopShell.tsx stays within the
  untested-module growth allowance (it had reached 1341 lines against a
  1334 cap once merged with main), which failed Build and test.
- Note in useViewerPluginGuard that layoutOptions.viewer comes from the
  launch URL and is fixed for the page's lifetime, so the render-time
  file-tools flag can never go stale and needs no reset on unmount.

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: giswqs <giswqs@gmail.com>
2026-10-19 20:58:04 -04:00

4.4 KiB

Sharing & Embedding

Once you have a map you like, you can publish it as a public link and embed it in any web page. This tutorial covers both. See Embedding & Sharing for the full reference.

1. Connect your account

Sharing uploads to share.geolibre.app.

  • Web app: open Project → Share... and click Sign in to share.geolibre.app. Approve the access request in the popup that opens — you are connected for the browser session.
  • GeoLibre Desktop: click the same Sign in to share.geolibre.app button. The sign-in opens in your system browser, and the desktop app keeps the session in your OS credential store.
  • Fallback (any build): paste a personal API token into Settings → Environment Variables → Share.GeoLibre API token. Create one under Settings → API tokens at share.geolibre.app/settings.

2. Share the project

  1. Build your map: add layers, style them, and set the map view you want viewers to land on.
  2. Open Project → Share....
  3. Confirm the project title and upload. GeoLibre returns a public URL to a .geolibre.json file, for example:
    https://share.geolibre.app/you/my-map.geolibre.json
    

The shared file captures the same layers, styles, plugin state, and map view as a local save. Layers that read files on your computer are the exception: the dialog lists them as missing before you share, since share.geolibre.app stores the project file and never your data files. See Sharing local data for how to host them instead.

3. Open the shared map

Anyone can open the shared project in the live viewer by passing it as the url parameter:

https://web.geolibre.app/?url=https://share.geolibre.app/you/my-map.geolibre.json

4. Embed it in a page

Use an <iframe> and the embed parameters to control the chrome. For a clean, map-only embed:

<iframe
  src="https://web.geolibre.app/?url=https://share.geolibre.app/you/my-map.geolibre.json&amp;maponly"
  title="GeoLibre map"
  width="100%"
  height="600"
  style="border: 0;"
  loading="lazy"
  allow="fullscreen; geolocation"
></iframe>

Adjust the look with parameters (they combine):

  • maponly hides all chrome, leaving only the map.
  • layout=viewer gives a read-only map: Layers, View, Controls, basemaps, and search/identify stay, while everything that edits the project is hidden.
  • draw, together with layout=viewer, lets readers sketch geometry on the map with the geometry editor while the rest of the viewer stays read-only. See Drawing in a viewer embed.
  • layout=compact keeps a slim, icon-only toolbar.
  • toolbar=none hides the top toolbar while keeping panels and the status bar.
  • panels=none hides the side and bottom panels but keeps the toolbar.
  • theme=dark forces the dark theme on load.

Reach for layout=viewer when readers should be able to toggle layers and explore the data but not change it, and maponly when the map is a figure in your page rather than something to interact with.

See the full parameter table.

5. Drive the map from your page

URL parameters configure the embed once, at load. To keep talking to it — fly to the record someone just clicked in your own UI, and hear what they do inside the map — install the typed client:

npm install @geolibre/embed
import { connect } from "@geolibre/embed";

const map = await connect(document.querySelector("iframe"), {
  origin: "https://web.geolibre.app",
});

map.on("selectionChanged", ({ featureIds }) => showRecordFor(featureIds[0]));

async function focusField(field) {
  await map.setView({ bbox: field.bbox });
  await map.highlightFeature({ layerId: "fields", filter: { parcel_id: field.id }, fit: true });
}

This works only against a deployment that has allowlisted your page's origin — web.geolibre.app has not, so the runtime API is for your own hosted build. See Talking to the map at runtime for the allowlist, the full command list, and the raw postMessage protocol if you would rather not add a dependency.

Next steps