{"id":290,"date":"2023-09-10T13:07:46","date_gmt":"2023-09-10T13:07:46","guid":{"rendered":"https:\/\/editor.mediahack.co.za\/databites\/?p=290"},"modified":"2025-11-17T17:41:35","modified_gmt":"2025-11-17T17:41:35","slug":"leaflet-and-sveltekit","status":"publish","type":"post","link":"https:\/\/outliereditor.co.za\/index.php\/2023\/09\/10\/leaflet-and-sveltekit\/","title":{"rendered":"Building projects with Leaflet and SvelteKit"},"content":{"rendered":"\n<p><a href=\"https:\/\/leafletjs.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Leaflet.js<\/a> is still my go-to library when I need to make a map. Using Leaflet with vanilla Javascript is pretty simple: add the Leaflet library and CSS file, add a few lines of code and you&#8217;re done. The Leaflet site has a <a href=\"https:\/\/leafletjs.com\/examples\/quick-start\/\">fantastic starter tutorial<\/a> on this. <\/p>\n\n\n\n<p>More recently I&#8217;ve been building projects in SvelteKit, which needs a slightly different setup to work. Mostly you need to account for things like checking whether the code is running in the browser.<\/p>\n\n\n\n<p>This is the bare-bones SvelteKit-Leaflet setup I use for most projects. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install Leaflet<\/h2>\n\n\n\n<p>Starting with a working SvelteKit app, install Leaflet: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm i leaflet<\/code><\/pre>\n\n\n\n<p>Next &#8230; <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Create a map component<\/h2>\n\n\n\n<p>Create a component file in the src\/lib directory, or wherever you put your components files. In this example, I created it here: <strong>src\/lib\/Map.svelte<\/strong>\/<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\nimport { onMount, onDestroy } from 'svelte';\nimport { browser } from '$app\/environment';\n\nlet mapContainer;\nlet map;\n\nonMount(async () =&gt; {\n   if(browser) {\n      const leaflet = await import('leaflet');\n      map = leaflet.map(mapContainer).setView(&#91;-26.1925013,28.0100383], 13);\n\n\/\/ Add the tile layer\nleaflet.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', { attribution: '&amp;copy; &lt;a href=\"https:\/\/www.openstreetmap.org\/copyright\"&gt;OpenStreetMap&lt;\/a&gt; contributors'}).addTo(map);\n\n\/\/ Add a marker to the map\nleaflet.marker(&#91;-26.1925013,28.0100383]).addTo(map)\n\n   }\n});\n\nonDestroy(async () =&gt; {\n   if(map) {\n      map.remove();\n   }\n});\n&lt;\/script&gt;\n\n\n&lt;main&gt;\n   &lt;div bind:this={mapContainer}&gt;&lt;\/div&gt;\n&lt;\/main&gt;\n\n&lt;style&gt;\n   @import 'leaflet\/dist\/leaflet.css';\n   div {\n   height: 500px;\n   }\n&lt;\/style&gt;<\/code><\/pre>\n\n\n\n<p>This loads onMount, OnDestroy and browser from Svelte. Then, if the code is running in a browser, Leaflet is loaded into the mapContainer div. <\/p>\n\n\n\n<p>In the code above I set the view to a point in Johannesburg, South Africa: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.setView(&#91;-26.1925013,28.0100383]<\/code><\/pre>\n\n\n\n<p>You can also change the tile layers by altering the tile layer setup. The <a href=\"https:\/\/leaflet-extras.github.io\/leaflet-providers\/preview\/\" target=\"_blank\" rel=\"noreferrer noopener\">Leaflet Providers<\/a> page is a good place to start looking for base maps. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>leaflet.tileLayer(\n   'https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png',\n      { attribution: '&amp;copy;\n      &lt;a href=\"https:\/\/www.openstreetmap.org\/copyright\"&gt;OpenStreetMap&lt;\/a&gt; contributors'\n       }\n)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Add component to page<\/h2>\n\n\n\n<p>Import the map component into the page and display. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script&gt;\n    import Map from '$lib\/Map.svelte';\n&lt;\/script&gt;\n\n&lt;main&gt;\n    &lt;Map \/&gt;\n&lt;\/main&gt;<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><em>This post is largely based on <a href=\"https:\/\/dev.to\/khromov\/using-leaflet-with-sveltekit-3jn1\" target=\"_blank\" rel=\"noreferrer noopener\">this post<\/a> by Stanislav Khromov. I changed a few things and added some additional details. <\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re planning on building projects in SvelteKit, it needs a slightly different set-up to Leaflet.js. Here&#8217;s what you need to do to get it to work. <\/p>\n","protected":false},"author":1,"featured_media":86674,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[447,448,1387],"tags":[487,450,451,488],"newsletter-post":[],"site":[],"class_list":["post-290","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-databites","category-how-to","category-the-outlier","tag-leaflet","tag-mapping","tag-maps","tag-sveltekit"],"acf":{"big_number":"","big_number_caption":"","big_number_link":"","big_number_background":"","big_number_text_colour":"#000000","big_number_icon":false,"big_number_wide":"yes","featured_chart":false,"flourish_chart_id":"","flourish_sub_title":"","flourish_chart_width":"medium","is_newsletter_post":"No","post_style":"bc","show_on_front":"Yes","link_through":"Yes","chart_url":"","background_colour":"#0089AA","text_colour":"#FFFFFF"},"_links":{"self":[{"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/posts\/290","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/comments?post=290"}],"version-history":[{"count":4,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/posts\/290\/revisions"}],"predecessor-version":[{"id":89617,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/posts\/290\/revisions\/89617"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/media\/86674"}],"wp:attachment":[{"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/media?parent=290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/categories?post=290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/tags?post=290"},{"taxonomy":"newsletter-post","embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/newsletter-post?post=290"},{"taxonomy":"site","embeddable":true,"href":"https:\/\/outliereditor.co.za\/index.php\/wp-json\/wp\/v2\/site?post=290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}