JAMstack bundler for embeddable map applications
Find a file
doxa-maps 5f2d7e6bbc
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,dashboard): kill the top divider + reflow the map when the table collapses
- SPA sidebar: suppress the leading section divider on the FIRST nav group.
  Every section emitted a `.sep` rule before its header, so Prayer Mobilization
  (the first section) drew a 1px line directly under the header with nothing
  above it to divide. drawSide() now tracks a firstGroup flag and skips it.
- Research dashboard: when the table under the map collapses, resize the map to
  fill the freed space. The ResizeObserver alone missed the grid reflow at the
  instant the table cell flips to display:none (v-show), leaving the map canvas
  at its old size (gray gap). DashboardMapPanel now also resizes on the
  'toggleTable' bus event (rAF + a 280ms settle pass), with clean teardown.
2026-09-12 21:21:45 +00:00
.github/workflows doxa-maps — portable bundler for embeddable JAMstack maps 2026-09-10 01:53:07 +00:00
app-profiles fix(spa,dashboard): kill the top divider + reflow the map when the table collapses 2026-09-12 21:21:45 +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,dashboard): kill the top divider + reflow the map when the table collapses 2026-09-12 21:21:45 +00:00
library fix(spa): make embedded maps survive the sandboxed plugin iframe 2026-09-12 21:07:26 +00:00
public fix(spa,dashboard): kill the top divider + reflow the map when the table collapses 2026-09-12 21:21:45 +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.