SvelteKit Local Edge Functions: Edge on Localhost

Rodney Lab - Nov 14 '22 - - Dev Community

🧗🏽 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’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’s local area. We will soon be able to cache Edge function data, creating greater potential for optimising user experiences.

🧱 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.

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:

pnpm create svelte@next sveltekit-local-edge-functions && cd $_
Enter fullscreen mode Exit fullscreen mode

If (like me) you always forget the commands for starting a new Svelte project you might find this, create SvelteKit app cheatsheet useful.

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

pnpm add -D @fontsource/figtree @sveltejs/adapter-static
Enter fullscreen mode Exit fullscreen mode

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:

<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>
Enter fullscreen mode Exit fullscreen mode

The function in lines 5 – 10 will call our endpoint. Notice we fetch content form a URL which looks like it’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 – 26) while we await the actual response. Explore the Starting out Svelte and SvelteKit tutorial for a closer look as await blocks.

If you save the code and refresh the page now, however, you will get some errors in the Terminal. That’s because the ‘/geo’ 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 ‘/geo’ route. Create a netlify/edge-functions folder in the project root directory. Then, add a geo.ts file there with the following content:

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 });
};
Enter fullscreen mode Exit fullscreen mode

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 use with Deno Fresh. See the Deno Edge API docs for further details on data available within the context object.

Next we create a netlify.toml file to map this function code above to the ‘/geo’ route. Create the file in the project root folder and add this code:

[[edge_functions]]
path = "/geo"
function = "geo"
Enter fullscreen mode Exit fullscreen mode

🖥 Running Netlify Edge Functions Locally

Finally to give SvelteKit access to the ‘/geo’ endpoint (which the middleware is listening on), we will run the SvelteKit dev server within the Netlify dev CLICommand Line Interface. You can add this globally or as a project dev dependency:

pnpm add -D netlify-cli
Enter fullscreen mode Exit fullscreen mode

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

BROWSER=none pnpm netlify dev
Enter fullscreen mode Exit fullscreen mode

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.

The Netlify dev server will be running on http://localhost:8888/. 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:

pnpm build
BROWSER=none pnpm netlify dev -c \"pnpm run preview\" --targetPort 4173
Enter fullscreen mode Exit fullscreen mode

package.json Scripts

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

{
    "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...
}
Enter fullscreen mode Exit fullscreen mode

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

pnpm dev:edge
pnpm build
pnpm preview:edge
Enter fullscreen mode Exit fullscreen mode

That’s it… 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 clone the site from the Rodney Lab GitHub repo to try it out if you haven’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 consider supporting me through Buy me a Coffee.

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 @askRodney on Twitter and also askRodney on Telegram. Also, see further ways to get in touch with Rodney Lab. I post regularly on SvelteKit as well as Search Engine Optimisation among other topics. Also subscribe to the newsletter to keep up-to-date with our latest projects.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .