README and docs: a plugin's own page is /__leaf/<plugin>/<profile>, and auto is MapLibre

A fresh reader given only the README and HOWTO-join-the-table got through install, bun run dev and
the Studio. One gap: no address for a single plugin's page. The Capability 1 fold says each plugin's
folder holds "an index.html for previewing it", which reads as /plugin-designs/<plugin>/index.html,
and that 404s under bun run dev. The page is /__leaf/<plugin>/<profile>, and the Studio's list is
/__plugin-gallery/manifest.json. Both are now named.
Three smaller notes from the same reader:
- the README copied .env.example to .env while the HOWTO uses .env.local. Both work and .env.local
  wins; the README now uses .env.local too, which also keeps .env free for compose.yaml;
- the Mapbox token read as required; it is one of two ways to get a background;
- the 8090 port hint (DX_PB_PORT) was only in the HOWTO; it is now named where the README first
  mentions PocketBase.

Also, the engine rule (was a follow-up commit, f0e965e4d):
Since 2026-09-28 useMapProvider.js resolves `auto` to MapLibre, and Mapbox is an explicit choice:
"provider": "mapbox" plus a token. The docs still said "Mapbox when a token is available":
- README's map-engines row;
- how-to.md's provider section;
- the plugin-designer skill's props table, which even says to confirm in useMapProvider.js.
All three now state the current rule. So do four lines that told readers to set provider maplibre to
avoid needing a key: README's Get it running and its "No token" fold, .env.example's token comment,
and reference.md's no-key row.
Case-insensitive git grep "Mapbox when a token" over README.md, documentation/ and skills/: 3 before, 0 after.
This commit is contained in:
Doxa Maps 2026-09-29 10:24:46 +00:00
parent 0631522a2c
commit c92e857e01
5 changed files with 22 additions and 18 deletions

View file

@ -4,8 +4,8 @@
# An empty value means "use the default".
# ── Maps ─────────────────────────────────────────────────────────────────────────────────────────
# A Mapbox public token (starts with pk.) for the map backgrounds. Empty = no Mapbox background; set
# "provider": "maplibre" on a plugin (or ?provider=maplibre on a page) to draw with MapLibre, no key.
# A Mapbox public token (starts with pk.), used by maps that choose Mapbox ("provider": "mapbox", or
# ?provider=mapbox on a page). Empty is fine: maps draw with MapLibre by default, with no key.
# Production hosts pass the token through profile-config.tk; never bake it into a bundle.
VITE_MAPBOX_TOKEN=
# The data API the maps read when a plugin's profile does not name one (profile apiBaseUrl and a host

View file

@ -45,7 +45,7 @@ capabilities, three outputs, one shared library, one build.
| | |
|---|---|
| 🗺️ **Two map engines** | Every map draws with **Mapbox** or **MapLibre** (free, no key) — switch with `"provider"` in its settings or `?provider=maplibre` in the address. By default it uses Mapbox when a token is available, MapLibre otherwise. |
| 🗺️ **Two map engines** | Every map draws with **Mapbox** or **MapLibre** (free, no key) — switch with `"provider"` in its settings or `?provider=mapbox` in the address. By default it uses MapLibre; Mapbox is an explicit choice (`"provider": "mapbox"` and a token). |
| 🔑 **A key or a key service** | Give Mapbox a public token, or the address of a token service that hands one out — set once in the Plugin Studio header. |
| 🌍 **11 languages** | `?lang=` or `"locale"`, with Arabic right to left — [Languages](#languages). |
| 🧩 **Web components** | Each map is its own HTML tag, like `<all-people-groups>`, that works on any page — no framework needed. |
@ -344,7 +344,8 @@ Adding a version means adding a row, not writing code.
<summary><b>More about capability 1 — single element</b></summary>
The simplest plugin, and where every map starts: a folder with three files — the map's `.vue`, an
`index.js` that registers its tag, and an `index.html` for previewing it. The build turns it into
`index.js` that registers its tag, and an `index.html` for previewing it (under `bun run dev`, a plugin's own
page is `/__leaf/<plugin>/<profile>`). The build turns it into
one custom HTML tag, like `<all-people-groups>`, that works on any web page.
- **Example:** `plugin-designs/all-people-groups/` — every people group on one map.
@ -696,23 +697,26 @@ a higher-capability plugin from them — that's how the Research Gallery was bui
### Get it running
You need **git**, **[Bun](https://bun.sh)** and **Node ≥ 18**, plus a free
**[Mapbox](https://account.mapbox.com) public token** (it starts with `pk.`) so the maps have a
background. For Rudder's voice engine, also **[Go](https://go.dev/dl/) 1.22+**, then run
You need **git**, **[Bun](https://bun.sh)** and **Node ≥ 18**. The maps draw with the keyless MapLibre engine
by default; for Mapbox, add a free **[Mapbox](https://account.mapbox.com) public token** (it starts with `pk.`)
and choose `"provider": "mapbox"` (see *No Mapbox token?* below). For Rudder's voice engine, also **[Go](https://go.dev/dl/) 1.22+**, then run
`bash backend/rudder-engine/setup-runtime.sh` once; without Go, everything except voice works.
```bash
git clone --depth 1 https://git.nuxtbase.app/doxa-open/doxa-maps.git # latest code only: seconds, not hundreds of MB of history
cd doxa-maps
bun install --frozen-lockfile
cp .env.example .env # optional: paste your pk. token after VITE_MAPBOX_TOKEN=
cp .env.example .env.local # optional: paste your pk. token after VITE_MAPBOX_TOKEN= (.env works too; .env.local wins)
bun run dev # → open the URL Vite prints: that page is the Plugin Studio
```
No build needed first — the built maps are already in the repo. `bun run dev` also starts a local
PocketBase on port 8090 for the plugins that use a backend; it is downloaded on the first run. To start a
PocketBase on port 8090 for the plugins that use a backend; it is downloaded on the first run (if 8090 is
taken, set `DX_PB_PORT` in `.env.local`). To start a
plugin, copy `plugin-designs/template-bundle/` to `plugin-designs/<your-map>/`; the studio finds it
automatically. Then rename it as its own `README.md` says.
automatically. Then rename it as its own `README.md` says. Each plugin also has its own page while
`bun run dev` runs, at `/__leaf/<plugin>/<profile>` (for example `/__leaf/all-people-groups/all-people-groups`), and the
Studio's list of plugins is `/__plugin-gallery/manifest.json`.
To put the maps on your own site, take [the easiest path: drop-in](#where-the-folder-goes-three-routes).
@ -738,8 +742,8 @@ The studio is a plugin like any other: `plugin-designs/plugin-studio/plugin-stud
<details>
<summary><b>No Mapbox token? And other map settings</b></summary>
- **No token:** set `"provider": "maplibre"` on any plugin (or add `?provider=maplibre` to a map's
page) and it draws with MapLibre, which needs no key.
- **No token:** nothing to do. Every map draws with MapLibre by default, which needs no key. Mapbox is an
explicit choice: `"provider": "mapbox"` on a plugin (or `?provider=mapbox` on a map's page), plus a token.
- **Built pages** take a token from `?tk=pk.…` in the address, from a token you paste once into the
page, or from a token endpoint.
- Every command and prerequisite, per deployment method:

View file

@ -334,10 +334,10 @@ The engine is a **runtime parameter** — same bundle, no rebuild. Resolution or
(first defined wins): `profile-config.provider` → `?provider=` in the page URL →
`window.MAP_PROVIDER` → default `auto`.
`auto` picks **Mapbox when a token is available** (a `tk` in the profile-config, `window.MAP_TOKEN`,
`?tk=`, a token pasted once in the tree, the studio's ⚙ Settings, or a configured token URL) and
**MapLibre otherwise** — keyless, with no request to Mapbox. The repo ships no Mapbox token, so a
fresh checkout draws every map with MapLibre until you give it one. An explicit `provider` always wins.
`auto` is **MapLibre**: keyless, with no request to Mapbox. Since 2026-09-28 a token no longer chooses the
engine. **Mapbox** is an explicit `provider: "mapbox"`, and the token then authenticates it (a `tk` in the
profile-config, `window.MAP_TOKEN`, `?tk=`, a token pasted once in the tree, the studio's ⚙ Settings, or a
configured token URL). An explicit `provider` always wins.
```html
<!-- per embed -->

View file

@ -19,7 +19,7 @@ Each bundle is one self-contained `.js` file that registers a custom HTML elemen
| **See a change on the served site** | rebuild, then refresh (the dev server never writes `public/`) |
| **Repoint the API without a rebuild** | set `window.MAP_APP_API_URL` before the bundle loads |
| **Repoint the Mapbox token** | pass `tk` in `profile-config`, or set `window.MAP_TOKEN_URL` / build-config `tokenUrl` |
| **Run a map without a Mapbox key** | `"provider": "maplibre"` in `profile-config` (or `?provider=maplibre`) |
| **Run a map without a Mapbox key** | nothing: MapLibre is the default. To force it anyway: `"provider": "maplibre"` in `profile-config` (or `?provider=maplibre`) |
---

View file

@ -94,7 +94,7 @@ header sets all of them, which is how you test yours.
| Prop | Values | Channels, first found wins | Default |
|---|---|---|---|
| **Map engine** (`provider`) | `mapbox` · `maplibre` · `auto` (any case) | `profile-config` `"provider"` → `?provider=` in the page address → `window.MAP_PROVIDER`; an explicit choice always wins | `auto`: Mapbox when a token is available (any row below), MapLibre otherwise. Confirm in `library/composables/useMapProvider.js`, never assume it |
| **Map engine** (`provider`) | `mapbox` · `maplibre` · `auto` (any case) | `profile-config` `"provider"` → `?provider=` in the page address → `window.MAP_PROVIDER`; an explicit choice always wins | `auto`: MapLibre. A token no longer chooses the engine: Mapbox needs `"provider": "mapbox"` plus a token (any row below). Confirm in `library/composables/useMapProvider.js`, never assume it |
| **Language** (`locale`) | one of the 11 in `library/i18n/locales/` | `profile-config` `"locale"` (or `"lang"`) → `?lang=` / `?locale=` → `<html lang>` | English |
| **Mapbox token** (`tk`) | a public `pk.…` token | `profile-config` `"tk"` → `?tk=` on a generated page → `window.MAP_TOKEN`; generated pages also keep a token pasted once in the tree (browser storage) | none. The embed snippet's `YOUR_MAPBOX_TOKEN` placeholder counts as no token |
| **Token service** (`tokenUrl`) | a URL that returns a `pk.` token | `profile-config` `"tokenUrl"` (the element asks it when it has no token; the studio header's field feeds this) → on generated pages also `window.MAP_TOKEN_URL` → the build config's `tokenUrl` → same-origin `/api/maps/token` | none |