Using MapLibre v6 with Vite
Inside a bundler, import.meta.url does not reliably resolve to the worker file, so each project needs a one-time setWorkerUrl() call. With Vite, use the ?worker&url query to get a bundled, self-contained worker URL:
import { Map, setWorkerUrl } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url';
setWorkerUrl(workerUrl);
const map = new Map({
});
Use ?worker&url rather than a plain ?url: the dist worker imports its sibling maplibre-gl-shared.mjs, and ?url emits the worker file verbatim in production builds without that sibling — the worker then fails on its first import and no vector tiles load. ?worker&url routes the file through Vite's worker pipeline and emits a self-contained chunk.
In addition, the workshop template excludes MapLibre from Vite's dependency pre-bundling, because the worker can fail to bundle during that step:
export default defineConfig({
plugins: [sveltekit()],
optimizeDeps: {
exclude: ['maplibre-gl']
}
});
This one is our own workaround for this template rather than an upstream requirement — if your project works without it, you do not need it.
Other bundlers
webpack 5+, rspack and rsbuild use the same setWorkerUrl() call with a plain URL: setWorkerUrl(new URL('maplibre-gl/dist/maplibre-gl-worker.mjs', import.meta.url).toString()); See the v5 to v6 migration guide for the full list of changes.