mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
docs: migrate sveltekit server-side auth to svelte 5 (#30445)
* basic migration pass * update leftover slot * format: style
This commit is contained in:
1 parent
b623a4c403
commit
0ecd2446ff
1 file changed
+79
-75
@@ -276,24 +276,24 @@ Set up a listener for Auth events on the client, to handle session refreshes and
|
||||
|
||||
```svelte src/routes/+layout.svelte
|
||||
<script>
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
import { invalidate } from '$app/navigation'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
export let data;
|
||||
$: ({ session, supabase } = data);
|
||||
let { data, children } = $props()
|
||||
let { session, supabase } = $derived(data)
|
||||
|
||||
onMount(() => {
|
||||
const { data } = supabase.auth.onAuthStateChange((_, newSession) => {
|
||||
if (newSession?.expires_at !== session?.expires_at) {
|
||||
invalidate('supabase:auth');
|
||||
}
|
||||
});
|
||||
onMount(() => {
|
||||
const { data } = supabase.auth.onAuthStateChange((_, newSession) => {
|
||||
if (newSession?.expires_at !== session?.expires_at) {
|
||||
invalidate('supabase:auth')
|
||||
}
|
||||
})
|
||||
|
||||
return () => data.subscription.unsubscribe();
|
||||
});
|
||||
return () => data.subscription.unsubscribe()
|
||||
})
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
{@render children()}
|
||||
```
|
||||
|
||||
</StepHikeCompact.Code>
|
||||
@@ -327,15 +327,15 @@ export const load: PageServerLoad = async ({ locals: { supabase } }) => {
|
||||
|
||||
```svelte src/routes/+page.svelte
|
||||
<script>
|
||||
export let data;
|
||||
$: ({ countries } = data);
|
||||
let { data } = $props()
|
||||
let { countries } = $derived(data)
|
||||
</script>
|
||||
|
||||
<h1>Welcome to Supabase!</h1>
|
||||
<ul>
|
||||
{#each countries as country}
|
||||
<li>{country.name}</li>
|
||||
{/each}
|
||||
{#each countries as country}
|
||||
<li>{country.name}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
```
|
||||
|
||||
@@ -408,26 +408,31 @@ export const actions: Actions = {
|
||||
|
||||
```svelte src/routes/auth/+page.svelte
|
||||
<form method="POST" action="?/login">
|
||||
<label>
|
||||
Email
|
||||
<input name="email" type="email" />
|
||||
</label>
|
||||
<label>
|
||||
Password
|
||||
<input name="password" type="password" />
|
||||
</label>
|
||||
<button>Login</button>
|
||||
<button formaction="?/signup">Sign up</button>
|
||||
<label>
|
||||
Email
|
||||
<input name="email" type="email" />
|
||||
</label>
|
||||
<label>
|
||||
Password
|
||||
<input name="password" type="password" />
|
||||
</label>
|
||||
<button>Login</button>
|
||||
<button formaction="?/signup">Sign up</button>
|
||||
</form>
|
||||
```
|
||||
|
||||
```svelte src/routes/auth/+layout.svelte
|
||||
<script>
|
||||
let { children } = $props()
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
</nav>
|
||||
</header>
|
||||
<slot />
|
||||
|
||||
{@render children()}
|
||||
```
|
||||
|
||||
```svelte src/routes/auth/error/+page.svelte
|
||||
@@ -512,25 +517,25 @@ To ensure that `hooks.server.ts` runs for every nested path, put a `+layout.serv
|
||||
|
||||
```svelte src/routes/private/+layout.svelte
|
||||
<script>
|
||||
export let data;
|
||||
$: ({ supabase } = data);
|
||||
let { data, children } = $props()
|
||||
let { supabase } = $derived(data)
|
||||
|
||||
$: logout = async () => {
|
||||
const { error } = await supabase.auth.signOut();
|
||||
if (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
const logout = async () => {
|
||||
const { error } = await supabase.auth.signOut()
|
||||
if (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<header>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
</nav>
|
||||
<button on:click={logout}>Logout</button>
|
||||
<nav>
|
||||
<a href="/">Home</a>
|
||||
</nav>
|
||||
<button onclick={logout}>Logout</button>
|
||||
</header>
|
||||
<main>
|
||||
<slot />
|
||||
{@render children()}
|
||||
</main>
|
||||
```
|
||||
|
||||
@@ -561,55 +566,54 @@ using ((select auth.uid()) = user_id);
|
||||
```
|
||||
|
||||
```svelte src/routes/private/+page.server.ts
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { PageServerLoad } from './$types'
|
||||
|
||||
export const load: PageServerLoad = async ({ depends, locals: { supabase } }) => {
|
||||
depends('supabase:db:notes');
|
||||
const { data: notes } = await supabase.from('notes').select('id,note').order('id');
|
||||
return { notes: notes ?? [] };
|
||||
};
|
||||
depends('supabase:db:notes')
|
||||
const { data: notes } = await supabase.from('notes').select('id,note').order('id')
|
||||
return { notes: notes ?? [] }
|
||||
}
|
||||
```
|
||||
|
||||
```svelte src/routes/private/+page.svelte
|
||||
<script lang="ts">
|
||||
import { invalidate } from '$app/navigation';
|
||||
import type { EventHandler } from 'svelte/elements';
|
||||
import { invalidate } from '$app/navigation'
|
||||
import type { EventHandler } from 'svelte/elements'
|
||||
|
||||
import type { PageData } from './$types';
|
||||
import type { PageData } from './$types'
|
||||
|
||||
export let data: PageData;
|
||||
$: ({ notes, supabase, user } = data);
|
||||
let { data } = $props()
|
||||
let { notes, supabase, user } = $derived(data)
|
||||
|
||||
let handleSubmit: EventHandler<SubmitEvent, HTMLFormElement>;
|
||||
$: handleSubmit = async (evt) => {
|
||||
evt.preventDefault();
|
||||
if (!evt.target) return;
|
||||
const handleSubmit: EventHandler<SubmitEvent, HTMLFormElement> = async (evt) => {
|
||||
evt.preventDefault()
|
||||
if (!evt.target) return
|
||||
|
||||
const form = evt.target as HTMLFormElement;
|
||||
const form = evt.target as HTMLFormElement
|
||||
|
||||
const note = (new FormData(form).get('note') ?? '') as string;
|
||||
if (!note) return;
|
||||
const note = (new FormData(form).get('note') ?? '') as string
|
||||
if (!note) return
|
||||
|
||||
const { error } = await supabase.from('notes').insert({ note });
|
||||
if (error) console.error(error);
|
||||
const { error } = await supabase.from('notes').insert({ note })
|
||||
if (error) console.error(error)
|
||||
|
||||
invalidate('supabase:db:notes');
|
||||
form.reset();
|
||||
};
|
||||
invalidate('supabase:db:notes')
|
||||
form.reset()
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>Private page for user: {user?.email}</h1>
|
||||
<h2>Notes</h2>
|
||||
<ul>
|
||||
{#each notes as note}
|
||||
<li>{note.note}</li>
|
||||
{/each}
|
||||
{#each notes as note}
|
||||
<li>{note.note}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<form on:submit={handleSubmit}>
|
||||
<label>
|
||||
Add a note
|
||||
<input name="note" type="text" />
|
||||
</label>
|
||||
<form onsubmit={handleSubmit}>
|
||||
<label>
|
||||
Add a note
|
||||
<input name="note" type="text" />
|
||||
</label>
|
||||
</form>
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user