[BUG] fix maplibre-gl v6 map embeds not rendering - #467
Conversation
maplibre-gl v6 ships ESM-only. Its worker (maplibre-gl-worker.mjs) statically imports a sibling chunk (maplibre-gl-shared.mjs), and per the v5->v6 migration guide, bundler consumers must call setWorkerUrl() explicitly since import.meta.url no longer resolves the worker inside a bundle. Rspack's asset handling for new URL(..., import.meta.url) only emits the referenced file, not its sibling import, so maplibre-gl-shared.mjs 404s (silently, since the dev server's SPA fallback serves index.html for the missing path with a text/html content type). The worker then fails an opaque module load, the map never fires load/idle, and nothing past the background layer paints, matching the blank map on the branch deploy. Copy both worker files verbatim into static/ via a prestart/prebuild script instead, and point setWorkerUrl() at that static path with useBaseUrl() so it respects the site's baseUrl in PR preview deploys. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: John McCall <john@overturemaps.org>
🗺️ OMF Docs previews are live!
Auto-gen schema site is now available. This is an early preview of a future workflow where we will automatically generate and publish reference docs for the Overture Maps Format schema. The auto-gen schema site may contain incomplete or inaccurate information as we are still refining the generation process, so please compare against the repo schema site and refer to the official Overture documentation for authoritative information. Note ♻️ This preview updates automatically with each push to this PR. |
Super-linter summary
Super-linter detected linting errors For more information, see the GitHub Actions workflow run Powered by Super-linter NATURAL_LANGUAGE |
sustainable-npm@v3.0.0 defaults ignore-scripts to true in CI, which silently skips npm's automatic pre/post lifecycle hooks (prestart, prebuild) while still running the script explicitly invoked by npm run. That's why static/maplibre never got populated on the staging PR preview even though the fix worked locally. Verified by setting ignore-scripts=true locally and confirming npm run build still copies the worker files into build/maplibre. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: John McCall <john@overturemaps.org>
|
Copilot resolve the merge conflicts in this pull request |
There was a problem hiding this comment.
Pull request overview
This PR fixes MapLibre GL v6 embeds rendering blank by explicitly setting a statically served worker URL and ensuring both required worker chunks are available at runtime in Docusaurus builds (including CI environments that skip npm lifecycle hooks).
Changes:
- Update map components to use ESM imports, compute a baseUrl-aware worker URL, and call
maplibregl.setWorkerUrl(). - Add a script to copy
maplibre-gl-worker.mjsandmaplibre-gl-shared.mjsintostatic/maplibre/for reliable serving. - Chain the copy step into
npm start/npm run build, bumpmaplibre-glto^6.0.0, and ignore the generated static directory in ESLint/git.
Reviewed changes
Copilot reviewed 5 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/components/map.js | Switch to ESM MapLibre imports and set an explicit worker URL via useBaseUrl() before map creation. |
| src/components/buildings-map.js | Same worker URL + ESM import changes for the global buildings map embed. |
| scripts/copy-maplibre-worker.mjs | New script to copy both worker-related .mjs files into static/maplibre/. |
| package.json | Add copy-maplibre-worker script; chain it into start and build; bump maplibre-gl to v6. |
| package-lock.json | Lockfile updates for the MapLibre v6 dependency tree. |
| eslint.config.mjs | Ignore generated static/maplibre/ directory for linting. |
| .gitignore | Ignore generated static/maplibre/ directory in git. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: lowlydba <16843041+lowlydba@users.noreply.github.com>
Merge conflicts resolved in |
f974b5e
into
dependabot/npm_and_yarn/maplibre-gl-6.0.0
* [CHORE](deps)(deps): Bump maplibre-gl from 5.24.0 to 6.0.0 Bumps [maplibre-gl](https://github.com/maplibre/maplibre-gl-js) from 5.24.0 to 6.0.0. - [Release notes](https://github.com/maplibre/maplibre-gl-js/releases) - [Changelog](https://github.com/maplibre/maplibre-gl-js/blob/main/CHANGELOG.md) - [Commits](maplibre/maplibre-gl-js@v5.24.0...v6.0.0) --- updated-dependencies: - dependency-name: maplibre-gl dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix: use maplibre v6 ESM imports Co-authored-by: lowlydba <16843041+lowlydba@users.noreply.github.com> * [BUG] fix maplibre-gl v6 map embeds not rendering (#467) * [BUG] fix maplibre-gl v6 map embeds not rendering maplibre-gl v6 ships ESM-only. Its worker (maplibre-gl-worker.mjs) statically imports a sibling chunk (maplibre-gl-shared.mjs), and per the v5->v6 migration guide, bundler consumers must call setWorkerUrl() explicitly since import.meta.url no longer resolves the worker inside a bundle. Rspack's asset handling for new URL(..., import.meta.url) only emits the referenced file, not its sibling import, so maplibre-gl-shared.mjs 404s (silently, since the dev server's SPA fallback serves index.html for the missing path with a text/html content type). The worker then fails an opaque module load, the map never fires load/idle, and nothing past the background layer paints, matching the blank map on the branch deploy. Copy both worker files verbatim into static/ via a prestart/prebuild script instead, and point setWorkerUrl() at that static path with useBaseUrl() so it respects the site's baseUrl in PR preview deploys. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: John McCall <john@overturemaps.org> * Chain worker copy into build/start instead of npm pre-hooks sustainable-npm@v3.0.0 defaults ignore-scripts to true in CI, which silently skips npm's automatic pre/post lifecycle hooks (prestart, prebuild) while still running the script explicitly invoked by npm run. That's why static/maplibre never got populated on the staging PR preview even though the fix worked locally. Verified by setting ignore-scripts=true locally and confirming npm run build still copies the worker files into build/maplibre. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: John McCall <john@overturemaps.org> --------- Signed-off-by: John McCall <john@overturemaps.org> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lowlydba <16843041+lowlydba@users.noreply.github.com> * [BUG] Fix DuckDB query tests 403 on STAC fetch and stale fallback release Send a real User-Agent (CloudFront 403s Python-urllib from Actions runners), retry the STAC fetch, and source the fallback release from docusaurus.config.js so there's a single pin to keep fresh. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: John McCall <john@overturemaps.org> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: John McCall <john@overturemaps.org> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: John McCall <john@overturemaps.org> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lowlydba <16843041+lowlydba@users.noreply.github.com>

Fixes #468.
Branch deploy for #465 (the
maplibre-gl5→6 bump) has a blank map: staging.overturemaps.org/docs/pr/465-no-autogen/guides/buildings shows nothing past the background fill, vs. the working live buildings guide.Root cause
maplibre-glv6 ships ESM-only. Per the v5→v6 migration guide, bundler consumers must callsetWorkerUrl()explicitly, sinceimport.meta.urlno longer resolves the worker chunk from inside a bundle.The worker file (
maplibre-gl-worker.mjs) also statically imports a sibling chunk,maplibre-gl-shared.mjs. Rspack's asset handling fornew URL('maplibre-gl/dist/maplibre-gl-worker.mjs', import.meta.url)only emits the referenced file, not that sibling, somaplibre-gl-shared.mjs404s. It 404s silently too: the dev server's SPA fallback servesindex.htmlfor the missing path with atext/htmlcontent type instead of a real 404, so there's nothing in the console to point at. The worker's module import then fails with an opaque error, the map never firesload/idle, and nothing past thebackgroundlayer paints.Fix
Copy both worker files verbatim into
static/maplibre/viascripts/copy-maplibre-worker.mjs, and pointsetWorkerUrl()at that static path withuseBaseUrl()so it still resolves correctly on PR preview deploys with a non-rootbaseUrl.That copy step is chained directly into the
start/buildnpm scripts rather than aprestart/prebuildhook. Our CI useslowlydba/sustainable-npmwithignore-scriptsdefaulting totrueas of v3.0.0, which skips npm's automatic pre/post lifecycle hooks while still running whatever's explicitly invoked bynpm run. That's why the staging preview for this PR was still broken even though the fix worked in every local test,prebuildnever ran, sostatic/maplibre/stayed empty.Testing
Reproduced the blank map locally against #465's dependency bump (confirmed via WebGL
readPixels: canvas painted only the background color,map.isStyleLoaded()never wenttrue) before the fix, then confirmedloaded()/isStyleLoaded()both flip totrueand buildings/roads render after it, in bothdocusaurus startand adocusaurus build+docusaurus serve.Also set
ignore-scripts=truelocally to match CI, rannpm run build, and confirmedbuild/maplibre/*.mjsstill got populated and the served build rendered correctly, reproducing and fixing the actual staging failure mode.npm run lintandnpm run buildboth pass.