Setting up Supabase with Sveltekit

Sjors Wijsman
4 min readJun 14, 2021

In this article we’ll be going over how to setup Supabase with Sveltekit and how to display and send data over to Supabase with some easy error handling & user feedback. For authentication & sessions I recommend watching Svelte Mastery’s video on the subject. Find the example repo for this article here: https://github.com/SjorsWijsman/sveltekit-supabase/

Setting up a SvelteKit skeleton project

It’s very easy to get started with SvelteKit. Run the following command to get started with a skeleton project:

npm init svelte@next <folder-name>

You can also optionally setup TypeScript, ESLint and Prettier. For the example project, I used ESLint and Prettier. After going through the setup run the following commands to install dependencies and open up a local dev server.

cd <folder-name>
npm install
npm run dev -- --open

For more information on setting up SvelteKit read through Cameron Smith’s excellent writeup on the topic.

Setting up Supabase

First, sign in to Supabase and log in. Next, click the “New Project” button and create a name and password & select your preferred region for the database:

Creating a new project in Supabase

Click the create new project button to setup your database. Now, it should take some time for your database to initialise, so let’s get started with integrating it with SvelteKit.

Run the following command to install Supabase:

npm install @supabase/supabase-js

In the /src directory create a new directory called /lib. The lib directory is easily accessible from anywhere in your SvelteKit project with the $lib alias. In this /lib folder, create a new file called db.js. In this file we will be creating the Supabase client:

import { createClient } from '@supabase/supabase-js'const supabase = createClient(
import.meta.env.VITE_SUPABASE_URL,
import.meta.env.VITE_SUPABASE_ANON_KEY
)
export default supabase

Note: You might have to create a .eslintignore file and add “db.js” to it to prevent linter errors thrown by the import statements.

We can now import this Supabase client from anywhere in our Svelte project by importing:

import supabase from '$lib/db'

Now, to setup the environment variables, create a .env file in the root of your project directory and add the following variables:

VITE_SUPABASE_URL=<URL>VITE_SUPABASE_ANON_KEY=<ANON_KEY>

Go back to your Supabase dashboard to get the values we need for the environment variables. If your Supabase database is done initialising, head over to the settings in the sidebar navigation. Here, click on API and you should see a bunch of Config & API Keys. Grab the URL and API (anon public) key and throw the values respectively into the .env file.

With this, Supabase has been fully configured to work with SvelteKit.

Display data from Supabase

Let’s create some data in Supabase. Head over to the tables tab and click on New table. Give it a name (I called mine “games”) and optionally a description and create the table. Now we want to input some data so let’s create a column by clicking the New Column button. Let’s call it “title” and give it a type of text. Make sure Allow empty is unchecked.

First, let’s get the data from Supabase. In the index.svelte file create a script tag and add the following:

import supabase from '$lib/db'async function getData() {
const { data, error } = await supabase
.from('games')
.select()
if (error) throw new Error(error.message)

return data
}

This function should be fairly obvious, it deconstructs the response from Supabase into the data and error variables. If error isn’t null, throw the Error message to the client. Else, return the data.

Now we’re going to call this function from our Svelte code and add some simple error handling:

<h1>My favorite games</h1>{#await getData()}
<p>Fetching data...</p>
{:then data}
{#each data as game}
<li>{game.title}</li>
{/each}
{:catch error}
<p>Something went wrong while fetching the data:</p>
<pre>{error}</pre>
{/await}

This should be enough to retrieve the data from Supabase. I think the way Svelte handles these await catch blocks is absolutely beautiful and makes both error handling and user feedback extremely easy.

Send data to Supabase

The code to send data to Supabase is almost identical:

import supabase from '$lib/db'let newGame
let submit = false
async function sendData() {
const { data, error } = await supabase
.from('games')
.insert([
{ 'title': newGame }
])
if (error) throw new Error(error.message) return data
}

We use a new variable called newGame to store the input value and a submit boolean to handle submitting the data. The form & user feedback looks as follows:

<form on:submit|preventDefault={() => submit = true}>
<input type="text" bind:value={newGame}>
<input type="submit" value="Submit" on:click={() => submit = false}>
</form>
{#if submit}
{#await sendData()}
<p>Sending data...</p>
{:then data}
<p>Successfully sent data.</p>
{:catch error}
<p>Something went wrong while sending the data:</p>
<pre>{error}</pre>
{/await}
{/if}

Now, instead of calling the sendData() function directly inside the on:submit event, we set submit to true. Submit decides wether or not the {#await} block is there. Thus, when submit gets set to true, the await block gets put into the DOM and sendData() is called. The on:click event on the submit button makes sure submit is reset to false, to allow users to send data more than once (you could remove this to prevent users from sending data multiple times).

Conclusion

I think Supabase works extremely well together with Svelte’s await blocks and the serverless nature of SvelteKit. It makes setting up user feedback & error handling super easy and streamlined. Find the example repo for this article here: https://github.com/SjorsWijsman/sveltekit-supabase/

--

--

Sjors Wijsman

Communication & Multimedia Design student at HvA. Frontend Development Intern at De Voorhoede