SvelteKit SPA - React on route change (protected routes) #9370
-
Heyho, I'm really struggling to set up protected routes for a SPA. I think I have now tried everything to intercept every page load:
I'll go with a combination of 3. & 4., but I'm still unsure if it's the right way. Even if I would prefer 3. as it includes the group which I would like to identify protected routes. Does someone have an idea or am I missing something?
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
adapter: adapter({
fallback: 'index.html',
}),
}
};
export default config;
Cheers, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Seems like I was a little bit sleepy yesterday... I'm sure I checked this approach as well at some point. Solution routes/+layout.ts import { handleRouting, RouteType } from '$lib/utils/route';
import type { LayoutLoad } from './$types';
import { goto } from '$app/navigation';
import { get } from 'svelte/store';
import { userStore } from '$lib/stores/user';
export const ssr = false;
export const load = (async ({ route }) => {
const routeType = handleRouting(route.id || '')
const user = get(userStore);
const isUserLoggedIn = user.user_id !== '';
if (routeType === RouteType.PAGE_PROTECTED) {
if (!isUserLoggedIn) {
console.log("forwarding to /login")
goto('/login')
}
}
return {};
}) satisfies LayoutLoad; $lib/utils/route.ts const GROUPS_UNPROTECTED = ['(user)']
const API_USER_PROTECTED = ['/api/dk/init']
export function handleRouting(path: string): RouteType | null {
if (path === '') return null
if (path.startsWith('/api')) {
if (API_USER_PROTECTED.includes(path)) {
console.log("API_USER_PROTECTED")
return RouteType.API_USER_PROTECTED
} else {
console.log("API_BEARER_PROTECTED")
return RouteType.API_BEARER_PROTECTED
}
} else {
const isUnprotected = GROUPS_UNPROTECTED.find((group) => path.includes(group))
if (isUnprotected) {
console.log("PAGE_UNPROTECTED")
return RouteType.PAGE_UNPROTECTED
} else {
console.log("PAGE_PROTECTED")
return RouteType.PAGE_PROTECTED
}
}
}
export enum RouteType {
PAGE_PROTECTED,
PAGE_UNPROTECTED,
API_USER_PROTECTED,
API_BEARER_PROTECTED,
} |
Beta Was this translation helpful? Give feedback.
-
@LukaHarambasic Your solution appears to only work on initial page load. Am I missing something? Is there a better solution for this? |
Beta Was this translation helpful? Give feedback.
-
AFAIK, it does not work if you are already in a protected route, then you logout the user, then navigate to another protected route with the same layout. The load function in +layout.js is only called if you navigate to a different layout/route. If your route is at the same level, the validation would fail. Example:
The load() in /app/+layout.js will not be called |
Beta Was this translation helpful? Give feedback.
Seems like I was a little bit sleepy yesterday... I'm sure I checked this approach as well at some point.
Solution
routes/+layout.ts