SvelteKit 라우팅 — 파일 기반 라우팅 완전 정복
폴더를 만들면 라우트가 생기고, 파일 이름이 곧 규칙입니다 — SvelteKit의 라우팅은 파일 시스템이 곧 라우터입니다.
개념 정의
SvelteKit의 파일 기반 라우팅 은 src/routes/ 디렉토리의 폴더 구조가 곧 URL 구조가 되는 시스템입니다. +page.svelte 파일이 있는 폴더가 하나의 라우트가 됩니다.
기본 라우트
src/routes/
├── +page.svelte → /
├── about/
│ └── +page.svelte → /about
├── blog/
│ └── +page.svelte → /blog
└── contact/
└── +page.svelte → /contact
동적 라우트
대괄호 []로 동적 매개변수를 정의합니다.
src/routes/
├── blog/
│ ├── +page.svelte → /blog
│ └── [slug]/
│ └── +page.svelte → /blog/hello-world, /blog/my-post
├── users/
│ └── [id]/
│ ├── +page.svelte → /users/1, /users/2
│ └── settings/
│ └── +page.svelte → /users/1/settings
<!-- src/routes/blog/[slug]/+page.svelte -->
<script>
let { data } = $props();
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
// src/routes/blog/[slug]/+page.js
export async function load({ params }) {
// params.slug에 URL의 동적 부분이 들어옵니다
const post = await fetchPost(params.slug);
return { post };
}
나머지 매개변수 (Catch-all)
src/routes/
└── docs/
└── [...path]/
└── +page.svelte → /docs/a, /docs/a/b, /docs/a/b/c
// src/routes/docs/[...path]/+page.js
export async function load({ params }) {
// params.path = 'a/b/c' (문자열)
const segments = params.path.split('/');
return { segments };
}
선택적 매개변수
src/routes/
└── [[lang]]/
└── +page.svelte → / 또는 /ko 또는 /en
라우트 그룹
괄호 ()로 URL에 영향을 주지 않는 그룹을 만들 수 있습니다.
src/routes/
├── (marketing)/ # URL에 포함되지 않음
│ ├── +layout.svelte # 마케팅 전용 레이아웃
│ ├── about/
│ │ └── +page.svelte → /about
│ └── pricing/
│ └── +page.svelte → /pricing
├── (app)/ # URL에 포함되지 않음
│ ├── +layout.svelte # 앱 전용 레이아웃 (사이드바 등)
│ ├── dashboard/
│ │ └── +page.svelte → /dashboard
│ └── settings/
│ └── +page.svelte → /settings
레이아웃
<!-- src/routes/+layout.svelte — 루트 레이아웃 -->
<script>
let { children } = $props();
</script>
<nav>전역 네비게이션</nav>
{@render children()}
<footer>전역 푸터</footer>
<!-- src/routes/blog/+layout.svelte — 블로그 전용 레이아웃 -->
<script>
let { children } = $props();
</script>
<div class="blog-layout">
<aside>블로그 사이드바</aside>
<article>{@render children()}</article>
</div>
레이아웃은 중첩됩니다: 루트 레이아웃 > 블로그 레이아웃 > 페이지
레이아웃 리셋
상위 레이아웃을 건너뛰고 싶을 때 @ 접미사를 사용합니다.
src/routes/
├── +layout.svelte # 루트 레이아웃 (A)
├── blog/
│ ├── +layout.svelte # 블로그 레이아웃 (B)
│ ├── +page.svelte # A + B 적용
│ └── embed/
│ └── +page@.svelte # 모든 레이아웃 리셋 — 레이아웃 없음
네비게이션
<script>
import { goto, beforeNavigate, afterNavigate } from '$app/navigation';
import { page } from '$app/state';
// 현재 URL 정보
// page.url, page.params, page.route
// 프로그래밍 방식 네비게이션
function goToBlog() {
goto('/blog');
}
// 네비게이션 가드
beforeNavigate(({ cancel, to }) => {
if (hasUnsavedChanges) {
if (!confirm('저장하지 않은 변경사항이 있습니다.')) {
cancel();
}
}
});
afterNavigate(({ from, to }) => {
console.log(`${from?.url} → ${to?.url}`);
});
</script>
<!-- a 태그는 자동으로 클라이언트 사이드 네비게이션 -->
<a href="/blog">블로그</a>
<!-- 현재 경로 하이라이트 -->
<a href="/about" class:active={page.url.pathname === '/about'}>소개</a>
<button onclick={goToBlog}>블로그로 이동</button>
에러 처리
<!-- src/routes/+error.svelte -->
<script>
import { page } from '$app/state';
</script>
<h1>{page.status}</h1>
<p>{page.error?.message}</p>
면접 포인트
- "파일 기반 라우팅의 장점은?": 파일 구조가 곧 URL 구조이므로 프로젝트 구조만 봐도 앱의 라우트를 파악할 수 있습니다. 별도의 라우터 설정 파일이 필요 없습니다.
- "라우트 그룹은 언제 쓰나요?": 다른 레이아웃을 적용해야 하지만 URL 구조에는 영향을 주고 싶지 않을 때 사용합니다. 마케팅 페이지와 앱 페이지가 다른 레이아웃을 쓰는 것이 대표적 예시입니다.
정리
SvelteKit의 라우팅은 "폴더 구조 = URL 구조"라는 직관적인 원칙을 따릅니다. 동적 라우트, 그룹, 레이아웃 중첩, 에러 처리까지 모두 파일 시스템의 규칙으로 표현되니, 복잡한 설정 없이도 정교한 라우팅을 구현할 수 있습니다.
댓글 로딩 중...