Maps: each page asks for a fresh copy of its dx-maps script before adding it

A returning reader's browser may keep /dx-maps/ files for hours, as no cache rule is sent for them. Before adding a dx-maps script (Home, Pray, Adopt, Research, Deep Research, Posterverse and the regions' country posters), the page requests it once with cache 'no-cache': a 304 when unchanged, while a changed file replaces the stale copy. The script is then added at its plain address, so DX Maps' gallery still recognises it and never runs it twice.
This commit is contained in:
Doxa Life 2026-10-02 16:17:21 +00:00
parent 9a56ff4eb8
commit d6df2d385a
7 changed files with 95 additions and 7 deletions

View file

@ -2,10 +2,18 @@
// The posters' script is shared by every PosterSlot on the page: it loads once, on the first opening anywhere.
const POSTERS_TAG = 'dxm-poster-section'
const POSTERS_SCRIPT = '/dx-maps/country-posters/country-posters.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
let postersLoad: Promise<void> | null = null
function loadPosters(prayBaseUrl: string): Promise<void> {
if (customElements.get(POSTERS_TAG)) return Promise.resolve()
postersLoad ??= new Promise<void>((resolve, reject) => {
postersLoad ??= revalidate(POSTERS_SCRIPT).then(() => new Promise<void>((resolve, reject) => {
// the prayer API the posters read is set before the script runs
if (prayBaseUrl) window.MAP_APP_API_URL = prayBaseUrl
const script = document.createElement('script')
@ -13,7 +21,7 @@ function loadPosters(prayBaseUrl: string): Promise<void> {
script.onload = () => customElements.get(POSTERS_TAG) ? resolve() : reject(new Error('the posters bundle did not register'))
script.onerror = () => reject(new Error('the posters bundle failed to load'))
document.head.appendChild(script)
}).catch((err) => {
})).catch((err) => {
postersLoad = null // a later opening tries again
throw err
})

View file

@ -48,7 +48,19 @@ const adoptMapConfig = computed(() => JSON.stringify({
// away again, so a later page tries afresh; the page then shows without the map.
const MAP_TAG = 'dxm-simple-map'
const MAP_SCRIPT = '/dx-maps/doxa-simple-map/doxa-simple-map.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
function loadMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
return revalidate(MAP_SCRIPT).then(() => addMapBundle())
}
function addMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
const pending = document.querySelector<HTMLScriptElement>('script[data-dxl-map="' + MAP_TAG + '"]')
if (pending) {

View file

@ -44,10 +44,18 @@ const homeHref = () => `https://doxa.life${localePath('/')}`
// The gallery comes from this site's own /dx-maps/ copy; the script and every embed URL come from it.
const GALLERY_SCRIPT = '/dx-maps/doxa-maps-spa/doxa-maps-spa.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
useHead({
title: 'Deep Research',
meta: [{ name: 'robots', content: 'noindex' }],
script: [{ src: GALLERY_SCRIPT, defer: true, key: 'research-gallery' }]
meta: [{ name: 'robots', content: 'noindex' }]
})
// With no layout, this page sets <html lang dir> itself, as the public layout does for every other
@ -113,6 +121,15 @@ onMounted(() => {
gallery.addEventListener('tab-change', onTabChange)
gallery.addEventListener('doxa-language-request', onLanguageRequest)
host.value?.appendChild(gallery)
// its script, revalidated (above) and then added at its plain address, once per page load
if (!customElements.get('doxa-maps-spa') && !document.querySelector(`script[src="${GALLERY_SCRIPT}"]`)) {
revalidate(GALLERY_SCRIPT).then(() => {
if (document.querySelector(`script[src="${GALLERY_SCRIPT}"]`)) return
const script = document.createElement('script')
script.src = GALLERY_SCRIPT
document.head.appendChild(script)
})
}
})
watch(locale, (lang) => {

View file

@ -70,7 +70,19 @@ const homeMapConfig = computed(() => JSON.stringify({
// away again, so a later page tries afresh; the page then shows without the map.
const MAP_TAG = 'dxm-simple-map'
const MAP_SCRIPT = '/dx-maps/doxa-simple-map/doxa-simple-map.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
function loadMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
return revalidate(MAP_SCRIPT).then(() => addMapBundle())
}
function addMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
const pending = document.querySelector<HTMLScriptElement>('script[data-dxl-map="' + MAP_TAG + '"]')
if (pending) {

View file

@ -43,10 +43,18 @@ const homeHref = () => `https://doxa.life${localePath('/')}`
// The shell comes from this site's own /dx-maps/ copy; the script and every embed URL come from it.
const POSTERVERSE_SCRIPT = '/dx-maps/posterverse/posterverse.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
useHead({
title: 'Posterverse',
meta: [{ name: 'robots', content: 'noindex' }],
script: [{ src: POSTERVERSE_SCRIPT, defer: true, key: 'posterverse' }]
meta: [{ name: 'robots', content: 'noindex' }]
})
// With no layout, this page sets <html lang dir> itself, as the public layout does for every other
@ -110,6 +118,15 @@ onMounted(() => {
shell.addEventListener('tab-change', onTabChange)
shell.addEventListener('doxa-language-request', onLanguageRequest)
host.value?.appendChild(shell)
// its script, revalidated (above) and then added at its plain address, once per page load
if (!customElements.get('posterverse-app') && !document.querySelector(`script[src="${POSTERVERSE_SCRIPT}"]`)) {
revalidate(POSTERVERSE_SCRIPT).then(() => {
if (document.querySelector(`script[src="${POSTERVERSE_SCRIPT}"]`)) return
const script = document.createElement('script')
script.src = POSTERVERSE_SCRIPT
document.head.appendChild(script)
})
}
})
watch(locale, (lang) => {

View file

@ -45,7 +45,19 @@ const prayMapConfig = computed(() => JSON.stringify({
// away again, so a later page tries afresh; the page then shows without the map.
const MAP_TAG = 'dxm-simple-map'
const MAP_SCRIPT = '/dx-maps/doxa-simple-map/doxa-simple-map.js'
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
function loadMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
return revalidate(MAP_SCRIPT).then(() => addMapBundle())
}
function addMapBundle(): Promise<void> {
if (customElements.get(MAP_TAG)) return Promise.resolve()
const pending = document.querySelector<HTMLScriptElement>('script[data-dxl-map="' + MAP_TAG + '"]')
if (pending) {

View file

@ -60,10 +60,20 @@ const researchMapSlot = ref<HTMLElement | null>(null)
let unlockHeight: (() => void) | null = null
onMounted(() => { if (researchMapSlot.value) unlockHeight = lockPhoneHeight(researchMapSlot.value) })
onBeforeUnmount(() => unlockHeight?.())
// FRESH, NOT STALE: a returning reader's browser may keep /dx-maps/ files for hours (no cache rule is sent for them), so
// the script is asked for once with cache 'no-cache' before it is added (a 304 when unchanged; a changed file replaces the
// stale copy), then added at its PLAIN address, so DX Maps' gallery still recognises it and never runs it twice.
function revalidate(src: string): Promise<void> {
return fetch(src, { cache: 'no-cache', credentials: 'same-origin' })
.then((r) => { if (r.status === 200 && r.body) r.body.cancel() })
.catch(() => {})
}
// The prayer API the map reads is set before its script runs, and the script is added once per visit.
onMounted(() => {
onMounted(async () => {
if (runtimeConfig.public.prayBaseUrl) window.MAP_APP_API_URL = runtimeConfig.public.prayBaseUrl as string
const src = '/dx-maps/doxa-research-map/doxa-research-map.js'
if (customElements.get('doxa-research-map') || document.querySelector(`script[src="${src}"]`)) return
await revalidate(src)
if (!document.querySelector(`script[src="${src}"]`)) {
const script = document.createElement('script')
script.src = src