diff --git a/.env.example b/.env.example index 8349e38b..acdde93a 100644 --- a/.env.example +++ b/.env.example @@ -37,9 +37,8 @@ MOBILE_APP_ANDROID_PACKAGE=life.doxa.pray # Mapbox (used by the prayer map on /pray) NUXT_PUBLIC_MAPBOX_TOKEN=your-mapbox-public-token -# Research page: load the dx-maps tree from a maps CDN instead of this site's public/dx-maps copy. -# Unset = the local copy. The CDN must send Access-Control-Allow-Origin for the tree. -# NUXT_PUBLIC_DX_MAPS_BASE=https://maps-dev.nuxtbase.app/cdn/dx-maps +# Research page: the Research Gallery page it iframes. Unset = the default below. +# NUXT_PUBLIC_DX_MAPS_GALLERY_URL=https://maps-dev.nuxtbase.app/cdn/dx-maps/doxa-maps-spa/doxa-maps-spa/index.html # Cloudflare Turnstile NUXT_TURNSTILE_SITE_KEY=your-turnstile-site-key diff --git a/DX-MAPS-GALLERY.md b/DX-MAPS-GALLERY.md index a5f00c29..a7e640b9 100644 --- a/DX-MAPS-GALLERY.md +++ b/DX-MAPS-GALLERY.md @@ -9,7 +9,7 @@ on the site now loads from the same build tree. | | | |---|---| | `public/dx-maps/` | **New.** The dx-maps build tree (the gallery plus every map it opens, their data and assets), copied unchanged from the doxa-maps repo's `main` (`public/dx-maps/`). DX-life serves it from its own origin, so this site is the maps' CDN; no third-party host is involved. | -| `app/pages/research/index.vue` | **The Research Gallery.** The page loads one script (`/dx-maps/doxa-maps-spa/doxa-maps-spa.js`) and adds one element (``), sized to the viewport below the header; its `tree-base` is built at runtime from the page's own origin. The previous content (the "By Region" link, the single research map and the UUPG list) is **kept but switched off**: set `SHOW_LEGACY_RESEARCH = true` in the page to bring it back. | +| `app/pages/research/index.vue` | **The Research Gallery, as an iframe.** The page frames the gallery page hosted by the maps container (`NUXT_PUBLIC_DX_MAPS_GALLERY_URL`, default `https://maps-dev.nuxtbase.app/cdn/dx-maps/doxa-maps-spa/doxa-maps-spa/index.html`), sized to the viewport below the header, in the site's language. Nothing is loaded into the page's own document, and the page needs no `public/dx-maps/` copy. The previous content (the "By Region" link, the single research map and the UUPG list) is **kept but switched off**: set `SHOW_LEGACY_RESEARCH = true` in the page to bring it back. | | `app/composables/useDoxaMap.ts` | The home (engagement), pray (prayer) and adopt (adoption) maps now load `/dx-maps/doxa-simple-map/doxa-simple-map.js`; the research-map key loads `/dx-maps/doxa-research-map/doxa-research-map.js`. Mapbox GL moves from v3.3.0 to v3.24.0, the version the dx-maps bundles are built and tested with. | | `app/components/DoxaMapSlot.vue` | With no Mapbox token configured, it asks the map for the keyless MapLibre engine (see **Map engine**). With a token, the config passes through unchanged. | | `public/embed/map/index.html`, `public/research/doxa-research-map.html` | The same: bundles from `/dx-maps/`, Mapbox GL v3.24.0. | @@ -52,13 +52,12 @@ or `.env` is needed for this page. Without `DATABASE_URL`, the dev server only l `regions-dashboard`, `upg-100`, and so on). - Share and embed links in the maps point at this site's own `/dx-maps/` pages. -## Maps from a CDN instead of the local copy +## The gallery page it frames -Set `NUXT_PUBLIC_DX_MAPS_BASE` to a dx-maps tree URL, for example -`NUXT_PUBLIC_DX_MAPS_BASE=https://maps-dev.nuxtbase.app/cdn/dx-maps`. The Research page then loads the -gallery script and every map from there. That host must send `Access-Control-Allow-Origin` for the tree. -Unset (the default), the page uses this site's own `public/dx-maps/` copy, as above. The home, pray and adopt -maps still load from the local copy. +Set `NUXT_PUBLIC_DX_MAPS_GALLERY_URL` to frame another gallery host (for example the maps subdomain once it +exists). The page adds `lang` and either `tk` (with a Mapbox token configured) or `provider=maplibre`. +The home, pray and adopt maps still load from this site's `public/dx-maps/` copy; only the Research page +is independent of it. ## Updating the maps diff --git a/app/pages/research/index.vue b/app/pages/research/index.vue index 539b7579..3dbb7342 100644 --- a/app/pages/research/index.vue +++ b/app/pages/research/index.vue @@ -4,14 +4,10 @@ // "By Region" link that were here. Those three are NOT deleted: they are kept below, switched off by // SHOW_LEGACY_RESEARCH, so the previous page returns by flipping one constant. // -// The gallery is a web component served from DX-life's OWN origin (public/dx-maps/, a copy of -// the dx-maps build tree), so this site is its CDN: one script, one element, no third-party host. -// It reads its manifest and every child map from the same /dx-maps/ tree. See -// DX-MAPS-GALLERY.md at the repo root. -// -// The element is created in onMounted rather than written in the template: it is a custom element -// that only exists in the browser, so this keeps it out of SSR and out of Vue's component resolver -// without any nuxt.config change. +// On this branch the gallery is an IFRAME of the gallery page hosted by the maps container +// (NUXT_PUBLIC_DX_MAPS_GALLERY_URL, default the Plugin Studio container's /cdn). Nothing is loaded +// into this page's own document, and the page needs no public/dx-maps copy. See DX-MAPS-GALLERY.md +// at the repo root. import { buildUupgListTranslations } from '~/utils/uupgListTranslations' @@ -35,18 +31,21 @@ const researchProfileConfig = computed(() => JSON.stringify({ })) if (SHOW_LEGACY_RESEARCH) useTextHighlight() -// The dx-maps tree: NUXT_PUBLIC_DX_MAPS_BASE when set (a maps CDN), otherwise this site's own -// /dx-maps/ copy. The script and every embed URL come from the same tree. -const DX_MAPS_BASE = ((runtimeConfig.public as { dxMapsBase?: string }).dxMapsBase || '').replace(/\/+$/, '') -const GALLERY_SCRIPT = `${DX_MAPS_BASE || '/dx-maps'}/doxa-maps-spa/doxa-maps-spa.js` +useHead({ title: () => t('Research') }) -useHead({ - title: () => t('Research'), - script: [{ src: GALLERY_SCRIPT, defer: true, key: 'research-gallery' }] +// The gallery page follows the site's language (and the language switcher: a new language reloads the +// frame). With a Mapbox token configured, the maps use it; without one they use the keyless MapLibre +// engine, so the page works with no secrets at all. +const galleryUrl = computed(() => { + const pub = runtimeConfig.public as { dxMapsGalleryUrl?: string; mapboxToken?: string } + const url = new URL(pub.dxMapsGalleryUrl || 'https://maps-dev.nuxtbase.app/cdn/dx-maps/doxa-maps-spa/doxa-maps-spa/index.html') + url.searchParams.set('lang', locale.value) + if (pub.mapboxToken) url.searchParams.set('tk', pub.mapboxToken) + else url.searchParams.set('provider', 'maplibre') + return url.toString() }) const host = ref(null) -let gallery: HTMLElement | null = null let resizeObs: ResizeObserver | null = null // The gallery fills the viewport below the header. The header's height differs between desktop @@ -64,28 +63,10 @@ onMounted(() => { resizeObs = new ResizeObserver(fitBelowHeader) resizeObs.observe(header) } - - gallery = document.createElement('doxa-maps-spa') - // Every embed URL is built at RUNTIME: from NUXT_PUBLIC_DX_MAPS_BASE when set, otherwise from the - // origin serving this page, so the same build works on any host (laptop, staging, production) with - // nothing hardcoded. - gallery.setAttribute('tree-base', DX_MAPS_BASE || `${window.location.origin}/dx-maps`) - // The site's language drives the gallery's (and every map's); it follows the language switcher. - gallery.setAttribute('language', locale.value) - // With a Mapbox token configured, the maps use it. Without one (a fresh laptop), they use the - // keyless MapLibre engine, so the page works with no secrets at all. - const token = (runtimeConfig.public as { mapboxToken?: string }).mapboxToken || '' - if (token) gallery.setAttribute('profile-config', JSON.stringify({ tk: token })) - else gallery.setAttribute('provider', 'maplibre') - host.value?.appendChild(gallery) }) -watch(locale, (lang) => { gallery?.setAttribute('language', lang) }) - onBeforeUnmount(() => { resizeObs?.disconnect() - gallery?.remove() - gallery = null }) @@ -93,7 +74,9 @@ onBeforeUnmount(() => {