Skip to content

Using the same ID in the source with Svelte's {#key} will cause an error during re-rendering. #137

@groovyjovy

Description

@groovyjovy

Description

This error occurred after displaying this page and clicking the "Re-render" button.

chunk-OUI5SPXK.js?v=507a617c:660 Uncaught Error: Source "source-1" already exists.

	in <unknown>
	in GeoJSONSource.svelte
	in MapLibre.svelte
	in Plain.svelte
	in content.svelte.md
	in +page.svelte
	in +layout.svelte
	in layout.svelte
	in +layout.svelte
	in root.svelte

    at contexts.svelte.js:66:17
    at MapContext.waitForStyleLoaded (contexts.svelte.js:82:13)
    at MapContext.addSource (contexts.svelte.js:65:14)
    at RawSource.svelte:36:10
    at MapContext.waitForStyleLoaded (contexts.svelte.js:82:13)
    at RawSource (RawSource.svelte:35:9)
<script lang="ts">
	import {
		MapLibre,
		NavigationControl,
		ScaleControl,
		GlobeControl,
		GeoJSONSource,
		CircleLayer,
	} from 'svelte-maplibre-gl';

	let renderKey = $state(0);

	const geojsonData1 = {
		type: 'FeatureCollection' as const,
		features: [
			{
				type: 'Feature' as const,
				geometry: {
					type: 'Point' as const,
					coordinates: [137, 36] as [number, number]
				},
				properties: { name: 'Point 1' }
			}
		]
	};
</script>

<div class="mb-4">
	<button
		onclick={() => renderKey++}
		class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
	>
		Re-render (key: {renderKey})
	</button>
</div>

<MapLibre
	class="h-[55vh] min-h-[300px]"
	style="https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json"
	zoom={3.5}
	center={{ lng: 137, lat: 36 }}
>
	<NavigationControl />
	<ScaleControl />
	<GlobeControl />

	{#key renderKey}
		<GeoJSONSource id="source-1" data={geojsonData1}>
			<CircleLayer
				id="circle-1"
				paint={{
					'circle-radius': 10,
					'circle-color': '#ff0000'
				}}
			/>
		</GeoJSONSource>
	{/key}
</MapLibre>

This is probably the cause. The Svelte {#key xxx} block re-renders when xxx changes. svelte-maplibre-gl tries to add a source to the "map instance" during this re-render, but the instance already has a source with the same ID.

Is this behavior expected? Also, does this library have a solution (or a known workaround)?

addSource(id: string, source: SourceSpecification | CanvasSourceSpecification) {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions