It’s always good to have a template ready with the mix of technologies you use.
The other day I started using GitPod’s svelte-kit template and it’s been pretty handy. I think supabase would be a perfect addition, since the database is remote. So I’m forking svelte-kit-example
and adding supabase.
It should also be setup ready to do auth with supabase-ui-svelte
.
Setting up the template
First, I forked gitpod-io/sveltekit-example
and changed the name to supabase-sveltekit-example
:
# clone gitpod-io's repo
gh repo clone gitpod-io/sveltekit-example supabase-sveltekit-example
cd supabase-sveltekit-example
# rename origin to upstream, so we can merge changes
git remote rename origin upstream
# create the repo
gh repo create
# push to github
git push origin main
Then added supabase:
# install supabase template
npx svelte-add joshnuss/svelte-supabase
# convert .js to .ts
mv src/lib/db.js src/lib/db.ts
Configuring the template
Added an example query inside db.ts
:
export const products = {
async all() {
const { data } = await supabase
.from('products')
.select('*')
return data
}
}
In index.svelte
, db.ts
is imported and the example query is run inside the load()
function:
<script lang="ts" context="module">
import * as db from '$lib/db'
export async function load() {
const products = await db.products.all()
return {
props: { products }
}
}
</script>
<script lang="ts">
export let products
</script>
Adding authentication
Installed supabase-ui-svelte
:
npm i -D supabase-ui-svelte
Added a sign-in page:
<!-- src/routes/sign-in.svelte -->
<script lang="ts">
import Auth from 'supabase-ui-svelte'
import { supabase } from '$lib/db'
</script>
<div class="container">
<h1>Sign in</h1>
<Auth supabaseClient={supabase}/>
</div>
Then, added a Svelte store to wrap the user data. This way when a user signs in/out all subscribers are notified:
// in db.ts
// ...
import { readable } from 'svelte/store'
// ...
export const user = readable(supabase.auth.user(), set => {
supabase.auth.onAuthStateChange((event, session) => {
if (event == 'SIGNED_OUT') {
set(null)
}
})
})
Then we can use the user
store in the index page:
<!-- in src/routes/index.svelte -->
<script>
import { user, auth } from '$lib/db'
</script>
{#if $user}
<p>You are signed in as {$user.email}</p>
<button on:click={() => auth.signOut()}>Sign out</button>
{:else}
<nav>
<a href="/sign-in">Sign in</a>
</nav>
{/if}
NOTE: had some trouble running on gitpod, so I will have to retry this experiment again later.
GitPod Snapshot
http://gitpod.io/#https://github.com/joshnuss/supabase-sveltekit-example
Demo
Notes
- Should it run supabase locally? That would eliminate the need to setup .env