Skip to content

SvelteKit

View .md

Use the <instant-map> element directly in a SvelteKit page. The load function builds the first image on the server, and the element takes over in the browser.

Terminal window
npm install instantmap-js

Build the poster URL in +page.server.ts so it is part of the server HTML.

src/routes/+page.server.ts
import { staticUrl } from 'instantmap-js/server';
import { listings } from '$lib/listings';
const center: [number, number] = [-97.74, 30.27];
const zoom = 12;
export function load() {
const markers = listings();
return {
markers,
center,
zoom,
poster: staticUrl({ center, zoom, width: 1200, height: 640, ratio: 2, markers })
};
}

Define the element in onMount, then give it the markers. The element only exists in the browser, so import it there.

src/routes/+page.svelte
<script lang="ts">
import { onMount } from 'svelte';
import type { InstantMapElement } from 'instantmap-js';
let { data } = $props();
let map: InstantMapElement | undefined = $state();
onMount(async () => {
await import('instantmap-js');
if (map) map.markers = data.markers;
});
</script>
<instant-map
bind:this={map}
center={data.center.join(',')}
zoom={data.zoom}
style="display:block;position:relative;height:520px"
>
<img
src={data.poster}
alt="Map of Austin"
width="1200"
height="640"
fetchpriority="high"
style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover"
/>
</instant-map>

The <img> is inside the element and is rendered by SvelteKit, so it is in the HTML before any JavaScript runs. Check it:

Terminal window
curl -s https://your-site.example/ | grep -o '<img[^>]*static?[^>]*'

You should see an <img> whose src points at /static?.

Set markers as a property. Listen with an on attribute, and call methods on the bound element.

src/routes/+page.svelte
<script lang="ts">
import type { Marker } from 'instantmap-js';
let opened = $state('Click a price to open its card.');
function onmarkerclick(event: Event) {
const { marker } = (event as CustomEvent<{ marker: Marker }>).detail;
opened = `${marker.title}, ${marker.label}`;
}
</script>
<instant-map bind:this={map} {onmarkerclick} ...></instant-map>
<p>{opened}</p>
<button onclick={() => map?.flyTo({ center: [-97.743, 30.267], zoom: 15 })}>Show downtown</button>
  • Importing instantmap-js at the top of the file. It touches customElements, which does not exist on the server. Import it inside onMount.
  • Giving the map no height. It collapses to nothing.
  • Setting markers as an attribute. It is a property, so assign map.markers = ....
  • Building the poster URL in the browser. The server HTML then has no first image.
Add an Instant Map to my SvelteKit app. Follow https://instantmap.org/docs/frameworks/sveltekit.md exactly. Build the poster URL with staticUrl from instantmap-js/server in +page.server.ts, render it as an img inside the instant-map element, and import instantmap inside onMount before setting map.markers. Give the map a fixed height. Build, start the server, and confirm the HTML from curl contains an img with /static? in its src.

examples/sveltekit on GitHub