티스토리 뷰
https://kit.svelte.dev/docs/routing
😎 이 글은 공식문서를 번역한 것입니다.
SvelteKit에서는 /src/routes의 하위 디렉토리가 URL의 경로가 된다.
- src/routes => '/' 경로
- src/routes/about => '/about' 경로
- src/routes/blog/[slug] => 'blog/1234' 와 같이 파라미터를 갖는 경로
1. +page
💡 +page.svelte
+page.svelte 컴포너트는 페이지를 정의한다. 기본적으로 페이지는 초기 요청에 대해 SSR로 이뤄지고, 이후 탐색에 대해서는 CSR을 통해 브라우저에서 랜더링 된다.
<!-- src/routes/+page.svelte -->
<h1>Hello and welcome to my site!</h1>
<a href="/about">About my site</a>
<!-- src/routes/about/+page.svelte-->
<h1>About this site</h1>
<p>TODO...</p>
<a href="/">Home</a>
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
<h1>{data.title}</h1>
<div>{@html data.content}</div>
💡 +page.ts (혹은 +page.js)
load 함수를 export하여 페이지가 랜더링되기 전에 필요한 데이터를 load한다. 이 기능은 +page.svelte와 동일하게 실행된다. 즉, SSR중에는 서버에서 실행되고 클라이언트 탐색 중에는 브라우저에서 실행된다.
// src/routes/blog/[slug]/+page.ts
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
export const load = (({ params }) => {
if (params.slug === 'hello-world') {
return {
title: 'Hello world!',
content: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
}
throw error(404, 'Not found');
}) satisfies PageLoad;
✍️ $types
이것은 우리가 타입스크립트를 사용할 때 타입의 safety를 보장하기 위해 SvelteKit이 제공하는 파일이다. 예를들어, PageData로 export let data를 선언한것은 load로 부터 반환된 값이 무엇이든지 datadml 타입임을 타입스크립트에게 알려준다.
💡 +page.server.ts
load 함수는 서버에서 실행 된다면 (예를 들어, API KEY와 같은 private한 환경 변수에 접근하거나 DB로 부터 데이터를 fetch할 때), +page.ts에서 +page.server.ts로 이름을 바꾸고 PageLoad에서 PageServerLoad로 타입을 변경해야 한다.
// src/routes/blog/[slug]/+page.server.ts
import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load = (async ({ params }) => {
const post = await getPostFromDatabase(params.slug);
if (post) {
return post;
}
throw error(404, 'Not found');
}) satisfies PageServerLoad;
클라이언쪽에서 탐색을 하는 동안 SvelteKit은 서버로 부터 이 데이터를 로드할 것이다.
+page.ts와 마찬가지로 +page.server.ts도 옵션을 export할 수 있다. - prerender, ssr, csr
+page.server.ts는 또한 actions를 export 할 수 있다. load는 서버에서 데이터를 읽도록 한다면, actions는 <form> 엘리멘트를 사용하여 서버에 데이터를 쓸 수 있게 한다.
2. +error
만약 load하는 동안 에러가 발생한다면 SvelteKit은 디폴트 에러페이지를 랜더링 할 것이다. +error.svelte를 추가하여 각 route별로 에러페이지를 커스터마이징 할 수 있다.
<!-- src/routes/blog/[slug]/+error.svelte -->
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.status}: {$page.error.message}</h1>
3. +layout
지금까지 독립적인 컴포넌트로써 페이지를 취급했다. 하지만 많은 어플리케이션에서는 모든 페이지에서 보여야 하는 엘리먼트들이 존재한다 (푸터와 헤더 같은). 우리는 그것들을 +layout.svelte에 넣는다.
💡 +layout.svelte
모든 페이지에 적용할 레이아웃을 만들기 위해서는 src/routes/+layout.svelte 파일을 생성해야 한다. 필요한 것은 페이지 컨텐츠에 들어갈 <slot>을 포한하는 것이다.
<!-- src/routes/+layout.svelte -->
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
<slot></slot>
<!-- src/routes/+page.svelte -->
<h1>Home</h1>
<!-- src/routes/about/+page.svelte -->
<h1>About</h1>
이렇게 하면 nav는 항상 보일 것이고, 페이지를 이동할 떄마다 <h1>의 내용이 변경될 것이다.
레이아웃은 중첩될수 있다. 예를들어 /settings 아래 있는 페이지들에 적용 할 수 있는 레이아웃을 만들수 있다. (nav를 가진 최상위 레이아웃을 가진 채로)
<!-- src/routes/settings/+layout.svelte -->
<script lang="ts">
import type { LayoutData } from './$types';
export let data: LayoutData;
</script>
<h1>Settings</h1>
<div class="submenu">
{#each data.sections as section}
<a href="/settings/{section.slug}">{section.title}</a>
{/each}
</div>
<slot></slot>
💡 +layout.ts
+page.ts로부터 데이터를 로딩하는 +page.svelte 와 같이, +layout.svelte 컴포너틑 또한 +layout.ts안의 load함수로 부터 데이터를 가져올 수 있다.
// src/routes/settings/+layout.ts
import type { LayoutLoad } from './$types';
export const load = (() => {
return {
sections: [
{ slug: 'profile', title: 'Profile' },
{ slug: 'notifications', title: 'Notifications' }
]
};
}) satisfies LayoutLoad;
4. +server
페이지와 마찬가지로 +server.ts에 라우트를 정의할 수 있다. 이것은 우리가 응답을 완전히 제어할 수 있게 합니다. server.ts 파일은 GET, POST, PATH, PUT, DELETE, OPTIONS와 같은 HTTP 메소드에 해당하는 함수를 export한다. 이것은 RequestEvent를 인자로 갖고 Response를 반환한다.
// src/routes/api/random-number/+server.ts
import { error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET = (({ url }) => {
const min = Number(url.searchParams.get('min') ?? '0');
const max = Number(url.searchParams.get('max') ?? '1');
const d = max - min;
if (isNaN(d) || d < 0) {
throw error(400, 'min and max must be numbers, and min must be less than max');
}
const random = min + Math.random() * d;
return new Response(String(random));
}) satisfies RequestHandler;
'개발 > SvelteKit' 카테고리의 다른 글
SvelteKit - Page options (0) | 2023.03.30 |
---|---|
SvelteKit - Loading Data (0) | 2023.03.30 |
SvelteKit + Vite (0) | 2023.01.05 |
- Total
- Today
- Yesterday
- 견과류
- 스벨트
- 읍천리382
- 산과들에
- 닭가슴살
- React
- 다국어
- 하루견과
- 리액트
- Redux
- Next.js
- 프로틴
- 타입스크립트
- svelte
- 간식
- 프로트엔드
- 유지어터
- 을지로
- frontend
- Componenet
- 환경변수
- .env
- TypeScript
- recoil
- props
- useEffect
- 다이어트
- 타코
- react-i18next
- 프론트엔드
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |