diff --git a/documentation/architecture/embeddability.md b/documentation/architecture/embeddability.md index cd3d8b5cd..4709d1d3c 100644 --- a/documentation/architecture/embeddability.md +++ b/documentation/architecture/embeddability.md @@ -81,9 +81,9 @@ apply it. Rule of thumb: **a path with ≥2 directory segments under the tree ro page → serve it framable.** Portable ways to implement the split, by host: -- **Traefik** (nuxtbase/go-base): a higher-priority router on `PathRegexp(^/plugin-assets/[^/]+/[^/]+/)` - sets `Content-Security-Policy: frame-ancestors *` + clears `X-Frame-Options`. (Live example: - `/data/coolify/proxy/dynamic/doxa-maps-embed.yaml`.) +- **Traefik** (a self-hosted reverse proxy): a higher-priority router on `PathRegexp(^/plugin-assets/[^/]+/[^/]+/)` + sets `Content-Security-Policy: frame-ancestors *` + clears `X-Frame-Options`. (Live example: a Traefik + dynamic-configuration file on the test host.) - **Cloudflare Pages / Netlify**: a `_headers` file — `//*/* Content-Security-Policy: frame-ancestors *`. - **Nginx**: `location ~ ^/[^/]+/[^/]+/ { add_header Content-Security-Policy "frame-ancestors *"; }` - **GitHub Pages**: serves no custom headers → pages are framable by default (no frame-ancestors), which is already correct for direct embeds. diff --git a/documentation/how-to.md b/documentation/how-to.md index 9d6f33bbb..943992a5a 100644 --- a/documentation/how-to.md +++ b/documentation/how-to.md @@ -215,8 +215,8 @@ there are options:** site serves them, so **doxa-life is the CDN**. No third party. - **GitHub.** Push the built maps to a public GitHub repo and serve them free through **GitHub Pages or jsDelivr** — **GitHub is the CDN**. -- **doxa-base's built-in home (Forgejo).** doxa-base ships **Forgejo as a CDN** — push the maps - there and it serves them, with no extra service to set up. +- **A Git host you run (for example Forgejo).** Push the maps there and serve them from it, with + no extra service to set up. - **Anywhere else.** Any static host works — Cloudflare, an S3-style bucket, etc. Pick one home and **every partner site embeds the same map from it** — change the map once and it diff --git a/plugin-designs/dashboard-plus-grid/dashboard-plus-grid.vue b/plugin-designs/dashboard-plus-grid/dashboard-plus-grid.vue index d8f57f1e2..7a410d29d 100644 --- a/plugin-designs/dashboard-plus-grid/dashboard-plus-grid.vue +++ b/plugin-designs/dashboard-plus-grid/dashboard-plus-grid.vue @@ -223,7 +223,7 @@ function onDashboardFilter({ filterSet = {}, searchTerm = '' } = {}) { // Tier 1 takes a whole url, so it is COMPUTED rather than hardcoded: resolveEmbedBase() is the same // helper ShareButton uses (profileConfig.embedBaseUrl → window.MAP_EMBED_BASE_URL → the root the // built bundle derives from its own script url), so the link stays correct on doxa.life, on -// nuxtbase.app and in a dropped tree with no configuration. Hardcoding an absolute url here would +// the live test host and in a dropped tree with no configuration. Hardcoding an absolute url here would // pin every share to whichever host happened to build it. // // Note this is exactly the two-host defect class: research-dashboard standalone PASSES the same diff --git a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue index b52a00129..4c76d29dd 100644 --- a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue +++ b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue @@ -1124,7 +1124,7 @@ export default defineComponent({ // ★ THE CORS-READABLE COPY (generate-tree writes it beside this bundle, byte-identical). // A script embed on a partner page FETCHES the manifest cross-origin, and the live static layer // sends Access-Control-Allow-Origin only on paths INSIDE a folder of the tree — every bundle file - // and assets/ carry it, the ROOT manifest.json does not (measured 2026-09-25 on nuxtbase: the + // and assets/ carry it, the ROOT manifest.json does not (measured 2026-09-25 on the live test host: the // root 200 without it, doxa-maps-spa/ with it, even a 404). So on a foreign page the // copy is read FIRST (no CORS error in the host's console) and the root second; same-origin keeps // the root first. Script URLs still resolve against the TREE ROOT, never the copy's folder. diff --git a/plugin-designs/research-map-plus-grid/research-map-plus-grid.vue b/plugin-designs/research-map-plus-grid/research-map-plus-grid.vue index daf7c7faa..b0548ae4b 100644 --- a/plugin-designs/research-map-plus-grid/research-map-plus-grid.vue +++ b/plugin-designs/research-map-plus-grid/research-map-plus-grid.vue @@ -159,7 +159,7 @@ watch(textDir, reflectDir) // The absolute url this composite is shared and iframed as. Built here rather than written as a // literal because resolveEmbedBase() walks profileConfig.embedBaseUrl → window.MAP_EMBED_BASE_URL → // the root this bundle derives from its OWN script url, so the link is right on doxa.life, on -// nuxtbase.app and in a dropped tree with nothing configured. +// the live test host and in a dropped tree with nothing configured. // // It MUST be absolute, which is the non-obvious part. resolveShareUrl returns a tier-1 shareUrl // VERBATIM (embedBase.js:95 — `return whole.trim()`, no resolution), and ShareButton feeds the same diff --git a/plugin-designs/stack-demo/index.html b/plugin-designs/stack-demo/index.html index 97253c97b..91c001682 100644 --- a/plugin-designs/stack-demo/index.html +++ b/plugin-designs/stack-demo/index.html @@ -24,7 +24,7 @@

Capability 4, STACK variant — the shared StackLayout renders two elements (<research-dashboard-map> then <people-groups-grid>) on top of each other, each at its natural height, so you - scroll down through both on one page (the doxa-life / nuxtinator page-flow model). + scroll down through both on one page, as on a normal web page. Embed <stack-demo> anywhere and the host page provides the scroll.

diff --git a/plugin-designs/stack-demo/stack-demo.vue b/plugin-designs/stack-demo/stack-demo.vue index e76426800..b13cd539d 100644 --- a/plugin-designs/stack-demo/stack-demo.vue +++ b/plugin-designs/stack-demo/stack-demo.vue @@ -4,7 +4,7 @@ * * @element stack-demo * @description Groups TWO independent elements TOP-TO-BOTTOM so you can embed the pair on a page and - * SCROLL down through all of it (the doxa-life / nuxtinator page-flow model), instead of switching + * SCROLL down through all of it (the page-flow model of a normal host page), instead of switching * between them with tabs. Section 1 = the rich (facets + map + charts + * table); section 2 = the cap-2 (live pray.doxa.life). Each renders at its * NATURAL height; the host page scrolls.