SvelteKit Local Edge Functions: Edge on Localhost
Tags: svelte, webdev, tutorial, javascript
Published: 2022-11-14 12:45:51

---
title: "SvelteKit Local Edge Functions: Edge on Localhost"
published: "true"
description: "SvelteKit local Edge Functions: how you can bring the Netlify Edge to your localhost dev server for an improved developer experience."
tags: "svelte, webdev, tutorial, javascript"
canonical_url: "https://rodneylab.com/sveltekit-local-edge-functions/"
cover_image: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m022oveuijqosiw3y2b5.png"
---

## 🧗🏽 SvelteKit Local Netlify Edge Functions

In this post we see how you can run SvelteKit Local Edge functions locally on your dev server.  This can be helpful for improving your developer experience and shortening the feedback loop when debugging issues.  Using the Netlify CLI, we will see how you can run the Netlify middleware locally. That is injecting geolocation data without having to build your app in the cloud.  Hopefully you will find this a treasure, especially if you have adopted the test driven development paradigm and want to include Edge functionality in your local end to end tests.


## 😕 What are Edge Functions?

Edge functions are also known as middleware. They let us intercept visitor requests to our site and run additional code.  The Edge part means they run in the part of the content delivery network (CDN) closest to the site visitor, no matter where they are located globally.  This brings the advantages of personalising the page content to the user.  Within the Edge function environment, we can check the user&rsquo;s country, for example. In that case we could show content more relevant for site visitors from that country or even make sure we show the right data protection banners for the visitor&rsquo;s local area.  We will soon be able to <a aria-label="View Tweet on Deno CAching A P I" href="https://twitter.com/biilmann/status/1575574018974810112">cache Edge function data, creating greater potential for optimising user experiences</a>.


## 🧱 SvelteKit Local Edge Functions: What are we Building?

![SvelteKit Local Edge Functions: Screenshot: Image shows homepage and reads Welcome to SvelteKit Netlify Edge Geolocation data: IP: 127.0.0.1 Location: London, United Kingdom.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kw5a8408mr2hxdwujlgu.png)

This time we will just build a simple, single page site. In the Svelte code we will fetch user country, city and IP address.  You might use the IP address to secure certain content on your site (limiting access to particular IP address ranges). Country and city are useful if you want to customise content for the visitor.

Add the code below to an existing project or follow along to create reference code to use in future projects.

## ⚙️ Getting Started

To get going spin up a new SvelteKit app:

```shell
pnpm create svelte@next sveltekit-local-edge-functions && cd $_
```

If (like me) you always forget the commands for starting a new Svelte project you might find this, <a href="https://rodneylab.com/how-to-create-svelte-app/">create SvelteKit app cheatsheet</a> useful.

We will use a self-hosted font which you can install now:

```shell
pnpm add -D @fontsource/figtree @sveltejs/adapter-static
```
Next we customise the Svelte content.

## 🏡 SvelteKit Local Edge Functions: App Home Page

Replace the content in `src/routes/+page.svelte` with the code below:

```svelte
<script lang="ts">
	import '@fontsource/figtree';
	import '$lib/styles/global.css';

	async function getEdgeData() {
		const response = await fetch('/geo');

		const geoData = await response.json();
		return geoData;
	}
</script>

<main>
	<h1>Welcome to SvelteKit</h1>
<h2>Netlify Edge Geolocation data:</h2>
	{#await getEdgeData()}
		<section>
			<p><strong>IP</strong>: ...</p>
			<p><strong>Location</strong>: ...</p>
		</section>
	{:then { city, country, ip }}
		<section>
			<p><strong>IP</strong>: {ip}</p>
			<p><strong>Location</strong>: {city}, {country}</p>
		</section>
	{/await}
</main>
```

The function in lines `5`&thinsp;&ndash;&thinsp;`10` will call our endpoint.  Notice we fetch content form a URL which looks like it&rsquo;s within our app.  However, the Edge function will respond to the fetch and we do not need to add Svelte code for that path in our `src/routes` directory.

We use a Svelte `await` block to display placeholder content (lines `16`&thinsp;&ndash;&thinsp;`26`) while we await the actual response.  <a aria-label="Open the Svelte Kit tutorial" href="https://plus.rodneylab.com/tutorials/starting-out-svelte-sveltekit">Explore the Starting out Svelte and SvelteKit tutorial for a closer look as `await` blocks</a>.

If you save the code and refresh the page now, however, you will get some errors in the Terminal. That&rsquo;s because the &lsquo;`/geo`&rsquo; route does not exist. In fact, once we create it, we will need to run a different `dev` command so we can expose the Netlify Edge functions to our app running on localhost. We see this next.

## 📍 Edge Function

Next we can write our Edge function code which will be listening on the &lsquo;`/geo`&rsquo; route. Create a `netlify/edge-functions` folder in the project root directory. Then, add a `geo.ts` file there with the following content:

```typescript
import { Context } from 'https://edge.netlify.com';

export default async (_request: Request, context: Context) => {
	console.log('In edge function');

	const {
		ip,
		geo: {
			city,
			country: { name: country }
		}
	} = context;

	return Response.json({ ip, city, country });
};
```

The import in line `1` looks a little different to regular JavaScript imports, as does the `Response.json` call in line `14`. This is all just because Netlify Edge functions use the Deno JavaScript runtime, just like we <a href="https://rodneylab.com/tags/deno/">use with Deno Fresh</a>.  See the <a aria-label="Open the Edge function A P I docs" href="https://docs.netlify.com/edge-functions/api/#netlify-specific-context-object">Deno Edge API docs for further details on data available within the context object</a>.


Next we create a `netlify.toml` file to map this function code above to the &lsquo;`/geo`&rsquo; route.  Create the file in the project root folder and add this code:

```toml
[[edge_functions]]
path = "/geo"
function = "geo"
```

## 🖥 Running Netlify Edge Functions Locally

Finally to give SvelteKit access to the &lsquo;`/geo`&rsquo; endpoint (which the middleware is listening on), we will run the SvelteKit dev server within the Netlify dev <abbr>CLI<tool-tip inert role="tooltip">Command Line Interface</tool-tip></abbr>.  You can add this globally or as a project dev dependency:

```shell
pnpm add -D netlify-cli
```

Then you can start both the SvelteKit and Netlify Edge function dev server with a single command:

```shell
BROWSER=none pnpm netlify dev
```

The `BROWSER=none` part stops a new browser window opening automatically.

![SvelteKit Local Edge Functions: Screenshot: Image shows a the Terminal reading wiht a message: Server now ready on http://localhost:8888.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gtgu5x64lko5d947zt2y.png)

The Netlify dev server will be running on <a href="http://localhost:8888/">`http://localhost:8888/`</a>.  Go there and you should now see the SvelteKit site.  Notice how the `console.log` we added to the Edge function shows up in the Terminal.  This should help with debugging your Edge function.


## 🪚 Building the SvelteKit site and Running the Preview Server

To build and preview the site, again with Edge function access, run:

```shell
pnpm build
BROWSER=none pnpm netlify dev -c \"pnpm run preview\" --targetPort 4173
```

### `package.json` Scripts

For convenience, you can add a `dev:edge` and `preview:edge` script to your project `package.json` file:

```json
{
	"name": "sveltekit-static-edge-functions",
	"version": "0.0.1",
	"private": true,
	"scripts": {
		"dev": "vite dev",
		"dev:edge": "BROWSER=none pnpm netlify dev",
		"build": "vite build",
		"preview": "vite preview",
		"preview:edge": "BROWSER=none pnpm netlify dev -c \"pnpm run preview\" --targetPort 4173",
		"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
		"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
		"lint": "prettier --plugin-search-dir . --check . && eslint .",
		"format": "prettier --plugin-search-dir . --write ."
	}, // TRUNCATED...
}
```

Then you can just just the dev and preview servers with:

```shell
pnpm dev:edge
pnpm build
pnpm preview:edge
```
That&rsquo;s it&hellip; time to try this on your own project!

## 🙌🏽 SvelteKit Local Edge Functions: Wrapping Up

In this post, we saw how you can use SvelteKit local edge functions.  In particular, we saw:

- how to add **Netlify Edge functions to a SvelteKit** project,
- **installing and runing the Netlify CLI**,
- how to **expose the SvelteKit preview server to local Edge funtions**.

Hopefully this is something you can integrate into your test driven development processes. Please <a aria-label="Open the Rodney Lab Git Hub repo" href="https://github.com/rodneylab/sveltekit-static-edge-functions">clone the site from the Rodney Lab GitHub repo</a> to try it out if you haven&rsquo;t coded along. Hope you have found this post useful!  Let me know how you plan to use the code here in your own projects.  Also let me know about any possible improvements to the content above.

## 🙏🏽 SvelteKit Local Edge Functions: Feedback

If you have found this post useful, see links below for further related content on this site. I do hope you learned one new thing from the video. Let me know if there are any ways I can improve on it. I hope you will use the code or starter in your own projects. Be sure to share your work on Twitter, giving me a mention so I can see what you did. Finally be sure to let me know ideas for other short videos you would like to see. Read on to find ways to get in touch, further below. If you have found this post useful, even though you can only afford even a tiny contribution, please <a aria-label="Support Rodney Lab via Buy me a Coffee" href="https://rodneylab.com/giving/">consider supporting me through Buy me a Coffee</a>.

Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via <a aria-label="Reach out on Twitter" href="https://twitter.com/messages/compose?recipient_id=1323579817258831875">@askRodney</a> on Twitter and also <a aria-label="Contact Rodney Lab via Telegram" href="https://t.me/askRodney">askRodney on Telegram</a>. Also, see <a aria-label="Get in touch with Rodney Lab" href="https://rodneylab.com/contact/">further ways to get in touch with Rodney Lab</a>. I post regularly on <a aria-label="See posts on svelte kit" href="https://rodneylab.com/tags/sveltekit/">SvelteKit</a> as well as <a href="https://rodneylab.com/tags/seo/" aria-label="See posts on search engine optimisation">Search Engine Optimisation</a> among other topics. Also <a aria-label="Subscribe to the Rodney Lab newsletter" href="https://rodneylab.com/about/#newsletter">subscribe to the newsletter to keep up-to-date</a> with our latest projects.