SvelteKit - Loading Data
https://kit.svelte.dev/docs/load
😎 이 글은 공식문서를 번역한 것입니다.
+page.svelte 컴포넌트가 랜더링되기 전에 우리는 일부 데이터가 필요하다. 이것이 바로 load 함수에 정의되어있다.
1. Page data
+page.svelte 파일은 동일한 디렉토리에 +page.ts(혹은 +page.js)를 가질 수 있다. +page.ts는 load함수를 export하며, data prop을 통해 페이지에서 사용할 수 있는 값을 반환한다.
// 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;
<!-- src/routes/blog/[slug]/+page.svelte -->
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
</script>
<h1>{data.post.title}</h1>
<div>{@html data.post.content}</div>
load 함수는 서버와 브라우저 둘다에서 실행할 수 있다. 만약 load함수가 항상 서버에서 실행되어야 한다면 (private한 변수를 사용해야하기 때문에 - 예, 데이터베이스에 접근) 그때는 +page.ts 대신에 +page.server.ts을 사용한다.
blog 포스팅의 load함수의 현실적인 버전은 데이터베이스에서 데이터를 가져와야 하기 때문에 다음과 같은 모습이 된다.
// src/routes/blog/[slug]/+page.server.ts
import * as db from '$lib/server/database';
import type { PageServerLoad } from './$types';
export const load = (async ({ params }) => {
return {
post: await db.getPost(params.slug)
};
}) satisfies PageServerLoad;
✍️ 여기서 주목 할 점은 서버 load 함수는 추가적인 arguments에 접근해야하기 때문에 PageLoad에서 PageServerLoad로 타입이 바뀐것이다!
2. Layout Data
+layout.svelte 또한 +layout.ts 혹은 +layout.server.ts를 통해 데이터를 로드 할 수 있다.
// src/routes/blog/[slug]/+layout.server.ts
import * as db from '$lib/server/database';
import type { LayoutServerLoad } from './$types';
export const load = (async () => {
return {
posts: await db.getPostSummaries()
};
}) satisfies LayoutServerLoad;
<!-- src/routes/blog/[slug]/+layout.svelte -->
<script lang="ts">
import type { LayoutData } from './$types';
export let data: LayoutData;
</script>
<main>
<!-- +page.svelte is rendered in this <slot> -->
<slot />
</main>
<aside>
<h2>More posts</h2>
<ul>
{#each data.posts as post}
<li>
<a href="/blog/{post.slug}">
{post.title}
</a>
</li>
{/each}
</ul>
</aside>
레이아웃 load 함수로부터 반환된 데이터는 자식 +layout.svelte 컴포넌트와 +page.svelte 컴포넌트에서 사용 가능하다.
3. $page.data
+page.svelte 컴포넌트와 그 상위의 각 +layout.svelte 컴포넌트는 자체 데이터와 부모의 모든 데이터에 액세스할 수 있다. 어떤 경우에는 정반대가 필요하다. 부모 레이아웃에서 페이지 데이터 혹은 자식 레이아웃의 데이터레 접근할 필요가 있다.
예를 들어, root 레이아웃은 +page.ts 혹은 +page.server.ts 안에 있는 load 함수로 부터 반환된 title 속성에 접근하길 원한다. 이때 $page.data로 접근 할 수 있다.
<script>
import { page } from '$app/stores';
</script>
<svelte:head>
<title>{$page.data.title}</title>
</svelte:head>
$page.data에 대한 타입 정보는 App.PageData에 의해 제공된다.