SvelteKit universal-loads your routes. Wrap the map mount in <svelte:component> + a browser check so maplibre-gl only executes when running in the browser.
pnpm add maplibre-gl<script lang="ts">
import { onMount } from 'svelte';
import { browser } from '$app/environment';
import maplibregl, { type Map as MapLibreMap } from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
const MAP_STYLE = 'https://maps.guru/api/v1/styles/standard/light/style.json?key=YOUR_API_KEY';
let container: HTMLDivElement;
let map: MapLibreMap | undefined;
onMount(() => {
// Critical: SvelteKit may hydrate on the server during prerender.
// Skip maplibre-gl when browser === false.
if (!browser) return;
map = new maplibregl.Map({
container,
style: MAP_STYLE,
center: [77.209, 28.6139],
zoom: 11,
});
});
</script>
<div bind:this={container} class="map-canvas"></div>
Free-tier generous enough for real production traffic. 50,000 tile requests/month , no credit card.
Maplibre-gl touches document at import time. Guard the import with `import { browser } from "$app/environment"` and only mount the map on browser === true.
Yes. Prerender the layout + headings (great for SEO), then load the map via dynamic import + onMount only in the client.
The vocabulary behind vector tiles, styles, and geocoding, in plain language.
Join developers worldwide who trust maps.guru for their mapping needs. Start free, no credit card required.