JAMstack bundler for embeddable map applications
Find a file
doxa-maps 1cd2b46cd5
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
fix(spa): make embedded maps survive the sandboxed plugin iframe
Three fixes for the power-app SPA running as a go-base plugin (sandboxed
iframe, origin 'null' — where localStorage throws and root-absolute asset
paths misresolve under the /plugin-assets/<name>/ subpath):

- localStorage: wrap every theme/preference read+write in try/catch across
  the library (ProfileLoader, useMapTheme, uiStore). `typeof localStorage`
  is not enough — in a sandbox the object exists but ACCESS throws
  SecurityError. Sandboxed maps now boot themeless instead of crashing.
- assets: the SPA shell now injects an absolute assetsBase (derived from its
  own document.baseURI) into every mounted element's profile-config, so
  bundles fetch tables/vendor (Tabulator) from the correct subpath instead
  of a root-absolute /assets that 404s under /plugin-assets/doxa-maps-spa/.
- nav: revert the Prayer Mobilization section icon to 'heart' (the prayer
  glyph read as a header it is not).

Rebuilds every bundle (library-wide localStorage change).
2026-09-12 21:07:26 +00:00
.github/workflows doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
app-profiles feat: migrate research dashboard into doxa-maps as app-profile research-dashboard (self-contained; reuses @map library; includes facet/rail collapse + table density fixes) 2026-09-12 02:04:10 +00:00
capacitor/android doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
contributing doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
docs docs: showcase the REAL prayer map (doxa-simple-map prayer instance, Semantic Tree Legend) — replace the vibe-coded prayer-map scaffold screenshot 2026-09-11 23:51:14 +00:00
internal feat: apiBaseUrl as a first-class build-config field — every generated page bakes window.MAP_APP_API_URL (default pray.doxa.life); one knob to hot-swap to the self-hosted campaigns-server on go-base later, no code change 2026-09-12 03:15:36 +00:00
layouts fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
library fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
public fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
.env.example doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
.gitattributes doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
.gitignore doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
bun.lock feat: map provider swap — mapbox|maplibre engine + hybrid geocoder + provider badge; staging title doxa-maps 2026-09-11 21:47:25 +00:00
capacitor.config.json doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
CONTRIBUTING.md docs: skimmer pass — README to 1 diagram + 2 tables; how-to task index; docs/ router; CONTRIBUTING 384→61 (patterns+history → architecture) 2026-09-11 18:50:31 +00:00
index.html doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
LICENSE doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
package.json feat: map provider swap — mapbox|maplibre engine + hybrid geocoder + provider badge; staging title doxa-maps 2026-09-11 21:47:25 +00:00
README.md docs: showcase the REAL prayer map (doxa-simple-map prayer instance, Semantic Tree Legend) — replace the vibe-coded prayer-map scaffold screenshot 2026-09-11 23:51:14 +00:00
vite.config.js doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
vite.doxa-maps-build-config.json feat: apiBaseUrl as a first-class build-config field — every generated page bakes window.MAP_APP_API_URL (default pray.doxa.life); one knob to hot-swap to the self-hosted campaigns-server on go-base later, no code change 2026-09-12 03:15:36 +00:00

doxa-maps

A JAMstack bundler for composable, embeddable-first maps — one build outputs every map as a framework-agnostic web component, and composes them into a single-page application.

 app-profiles/<map>/            bun run build             where they run
 ┌──────────────────┐        ┌──────────────────┐      ┌─────────────────────────┐
 │ your map screens  │        │ one .js per map   │      │ ▸ any partner website    │
 │ (.vue) + colors + │──────► │ Vue + CSS inlined │────► │ ▸ a SPA (several maps    │
 │ data wiring       │        │ tree-shaken IIFE  │      │   in one layout)         │
 └──────────────────┘        │ + an index.html   │      │ ▸ Android/iOS app        │
      shared library/ ──────► │   per map page    │      │   (Capacitor)            │
      (@map: legend, map,    └──────────────────┘      └─────────────────────────┘
       controls — reused)     public/doxa-maps/…          one build → three products
The idea In one line
Bundle one self-contained .js = a custom HTML tag (<my-map>) — drop it on any page, no framework, no build step for the host
Embeddable by default every map also gets a generated standalone page — link it or iframe it (Start.me, Notion, any CMS)
Many maps, one bundle a bundle holds as many map screens as you want; add a .vue, rebuild
Lean & fast tree-shaken, Vue + CSS inlined → one request, faster than loading Vue from a CDN, nothing to 404
JAMstack hot-swap data API, token, even the map engine (Mapbox ↔ MapLibre) are runtime settings — change them with no rebuild
SPA compose several maps into one lazy-loaded layout → a full map site from the same build

✨ Don't write code? Describe your map to an AI coding agent — start at docs/tutorial.md.

Quickstart

Bun required (bun.sh; bun.lock is committed).

bun install
bun run build     # every app-profiles/<bundle>/ → public/doxa-maps/<bundle>/<bundle>.js
bun run dev       # live playground at http://localhost:5173/ — every map, clickable,
                  # with a copy-paste embed snippet for each

Embed a map

<link  href="https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.css" rel="stylesheet" />
<script src="https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js"></script>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v5.0.0/mapbox-gl-geocoder.min.js"></script>

<script src="/doxa-maps/my-map/my-map.js"></script>
<my-map profile-config='{"profile":"my-map","tk":"pk.eyJ..."}'></my-map>

Or skip the script tag entirely — iframe the map's generated page: /doxa-maps/<bundle>/<profile>/index.html. Both snippets are pre-generated per map in public/doxa-maps/manifest.json.

Docs

Read this When
why.md 2 min — the problem, the "map islands" idea, one diagram
tutorial.md build your first map, step by step
how-to.md task recipes — embed, iframe, SPA, colors, mobile, tokens
reference.md lookup — config fields, build scripts, contracts
architecture/ the deep end — full contracts and catalogs, when you want them

Contributors: CONTRIBUTING.md.

The output — real maps from this bundler

Every map below is a single self-contained bundle built by one bun run build, embeddable on any site with one <script> + tag. Colors are data-driven color strategies (@map/colors/).

Research Map — the full example

doxa-research-map · <doxa-research-map> — 7 tabs (prayer, adoption, engagement, regions, languages, religions) with clustering, filters, legends and poster export. This is the reference map that shows everything the library can do.

Research Map

Prayer Map — the flagship embed

doxa-simple-map · <doxa-map> · prayer instance · color: prayer-progress · Semantic Tree Legend — the prayer map built for embedding on partner sites at scale.

Prayer Map

Each also builds its own standalone page (/doxa-maps/<bundle>/<profile>/index.html) — link it or iframe it on a partner site. See docs/why.md for the idea and docs/how-to.md to build your own.

License

The doxa-maps template (library/ + build tooling) is Apache-2.0 — a permissive base everyone shares. Your maps under app-profiles/<bundle>/ are yours: your colors, API connections, and i18n. Full text: LICENSE.