diff --git a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue index 3c23fe887..2632b4426 100644 --- a/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue +++ b/plugin-designs/doxa-maps-spa/doxa-maps-spa.vue @@ -1354,8 +1354,13 @@ export default defineComponent({ const candidates = crossOrigin ? [copy, root] : [root, copy] // The tree's name comes from the build config (vite define), never a literal here: this was the // one tree path compiled into any bundle, so a renamed tree would have needed a gallery edit. - const devFallback = '/public/' + __DOXA_TREE_NAME__ + '/manifest.json' - if (!candidates.some(c => c.url === devFallback)) candidates.push({ url: devFallback, root: dirOf(devFallback) }) + // ★ THE DEV SERVER SERVES public/ AT THE ROOT. Reached as /public//…, Vite treats a built bundle as SOURCE + // and injects an import into its IIFE, so a child loaded as a classic script throws "Cannot use import statement + // outside a module" (measured on the staging page, 2026-10-03). So the root path comes first, served as the raw + // build; /public// stays last, for a plain static server of the repository, which transforms nothing. + for (const devFallback of ['/' + __DOXA_TREE_NAME__ + '/manifest.json', '/public/' + __DOXA_TREE_NAME__ + '/manifest.json']) { + if (!candidates.some(c => c.url === devFallback)) candidates.push({ url: devFallback, root: dirOf(devFallback) }) + } const tried = [] // Every mount waits for this gate (see FRESH BUNDLES above): it opens once the manifest's bundles are known // to be current, when no manifest can be read (fail-soft, as before), or after 8 s whatever happens.