はじめに
前提
SvelteKitでは、
+page.svelteや、 +page.tsに書くことでクライアントサイドでjsを動かすことができ、
*.server.tsに書くことでサーバーサイドでjsを動かすことができます。
今回やりたかったこと
- ログインしていればそのまま表示、
- ログインしていないときは任意のパスへとリダイレクトさせる
いつもはクライアントサイドのjsに処理を書いているが、
それだとログインしていなくても一瞬ログイン後の画面が出てしまっていた。
(画面表示後にリダイレクト処理が動くため)
画面表示前に動くサーバーサイドでリダイレクトさせることでその事象を抑えたかったが、
普段クライアントサイドで書いているやり方ではリダイレクトさせることができなかったのでそのときのメモ。
クライアントサイドでリダイレクトさせる場合
+layout.svelte
<script lang="ts">
import { goto } from "$app/navigation";
import { onMount } from "svelte";
import { page } from "$app/store";
onMount(() => {
const session = getSession()
if(!session && $page.url.pathname !== '/auth') {
goto('/auth')
}
})
</script>
app
モジュールのgoto
を使うことでリダイレクトさせることができます。
(当然window.location.href = ""でもリダイレクトできます。)
※ goto
はonMount内でのみ使用できます。
この場合一瞬ですが、ログイン後の画面が表示されてしまいます。
goto
使い方
型
goto(url: string | URL, opts?: {
replaceState?: boolean | undefined;
noScroll?: boolean | undefined;
keepFocus?: boolean | undefined;
state?: any;
invalidateAll?: boolean | undefined;
} | undefined)
例
// example 1
goto('/auth')
// example 2
const base = 'https://hogehoge.com'
const url = new URL('/auth', base)
goto(url)
// example 3
const opt = {
replaceState: true
}
goto('/auth', opt)
こんな感じのようです
サーバーサイドでリダイレクトさせる場合
+layout.server.ts
import { redirect } from "@sveltejs/kit";
import supabase from "../supabase";
/** @type {import('./$types').PageServerLoad} */
export async function load({ url }) {
const session = await supabase.auth.getSession()
if (session.data.session) {
return session;
}
if (url.pathname !== '/auth') {
throw redirect(301, '/auth')
}
}
redirect
を使うことでリダイレクトさせることができます。
こちらであれば一瞬画面が表示されちゃうみたいなことはありませんでした。
redirect
使い方
型
redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308,
location: string)
例
// OK
redirect(301, '/auth')
// NG
redirect('/auth')
redirect(200, '/auth')