ルーティング
SvelteKit の中心は、 ファイルシステムベースのルーター です。アプリのルート(routes) — 例えばユーザーがアクセスできる URL パス — は、コードベースのディレクトリによって定義されます:
src/routesは最上位のルート(the root route)ですsrc/routes/aboutは/aboutルート(route)を作成しますsrc/routes/blog/[slug]は パラメータslugを使ったルート(route)を作成します。パラメータは、ユーザーからのリクエストが/blog/hello-worldのようなページに行われた場合に、動的にデータを読み込むために使用することができます
プロジェクトの設定 を編集することで、
src/routesから別のディレクトリに変更することができます。
ルート(route)のディレクトリはそれぞれ1つ以上の ルートファイル(route files) を格納します。ルートファイル(route files)には + という接頭辞が付いているので、それで見分けることができます。
これらのファイルについては後ほど詳しく紹介しますが、まずは SvelteKit のルーティングの仕組みを覚えるのに役立つ、いくつかの簡単なルールをご紹介します。:
- 全てのファイルはサーバーで実行できます
+serverファイル以外のすべてのファイルは、クライアントで実行されます+layoutと+errorファイルは、配置されているディレクトリおよびそのサブディレクトリに適用されます
+page
+page.svelte
+page.svelte コンポーネントはアプリのページを定義します。デフォルトでは、ページは最初のリクエストではサーバー (SSR) でレンダリングされ、その後のナビゲーションではブラウザ (CSR) でレンダリングされます。
<h1>Hello and welcome to my site!</h1>
<a href="/about">About my site</a><h1>About this site</h1>
<p>TODO...</p>
<a href="/">Home</a>SvelteKit は、フレームワーク固有の
<Link>コンポーネントではなく、<a>要素を使用してルート間のナビゲーションを行います。
ページは、 load 関数から data prop を介してデータを受け取ることができます。
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
<h1>{data.title}</h1>
<div>{@html data.content}</div><script lang="ts">
import type { PageProps } from './$types';
let { data }: PageProps = $props();
</script>
<h1>{data.title}</h1>
<div>{@html data.content}</div>Legacy mode
PagePropsは 2.16.0 で追加されました。以前のバージョンでは、代わりにPageDataを使用してdataプロパティを手動で型付けする必要がありました。詳細は $types をご参照ください。Svelte 4 では、代わりに
export let dataを使用します
+page.js
ページではたびたび、レンダリングの前になんらかのデータを読み込む必要があります。これに対応するため、load 関数をエクスポートする +page.js モジュールを追加しています:
import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */
export function function load({ params }: {
params: any;
}): {
title: string;
content: string;
}
load({ params: anyparams }) {
if (params: anyparams.slug === 'hello-world') {
return {
title: stringtitle: 'Hello world!',
content: stringcontent: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
}
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, 'Not found');
}import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
import type { type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageLoad } from './$types';
export const const load: PageLoadload: type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type PageLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
PageLoad = ({ params: Record<string, any>The parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object
params }) => {
if (params: Record<string, any>The parameters of the current page - e.g. for a route like /blog/[slug], a { slug: string } object
params.slug === 'hello-world') {
return {
title: stringtitle: 'Hello world!',
content: stringcontent: 'Welcome to our blog. Lorem ipsum dolor sit amet...'
};
}
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, 'Not found');
};この関数は +page.svelte とともに実行されます。サーバーサイドレンダリング中はサーバーで実行され、クライアントサイドナビゲーション中はブラウザで実行されます。API の詳細は load をご参照ください。
+page.js では、load だけでなくページの動作(behaviour)を設定するための値をエクスポートすることができます:
export const prerender = trueまたはfalseまたは'auto'export const ssr = trueまたはfalseexport const csr = trueまたはfalse
これらに関するより詳しい情報は page options をご覧ください。
+page.server.js
load 関数をサーバー上でのみ実行できるようにしたい場合 — 例えば、データベースからデータを取得したり、API キーのようなプライベートな環境変数にアクセスしたりする必要がある場合 — +page.js を +page.server.js にリネームし、PageLoad 型を PageServerLoad に変更します。
import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
/** @type {import('./$types').PageServerLoad} */
export async function function load(event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>): MaybePromise<void | Record<string, any>>load({ params: Record<string, any>The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.
params }) {
const const post: {
title: string;
content: string;
}
post = await const getPostFromDatabase: (slug: string) => {
title: string;
content: string;
}
getPostFromDatabase(params: Record<string, any>The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.
params.slug);
if (const post: {
title: string;
content: string;
}
post) {
return const post: {
title: string;
content: string;
}
post;
}
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, 'Not found');
}import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
import type { type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>PageServerLoad } from './$types';
export const const load: PageServerLoadload: type PageServerLoad = (event: ServerLoadEvent<Record<string, any>, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>PageServerLoad = async ({ params: Record<string, any>The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.
params }) => {
const const post: {
title: string;
content: string;
}
post = await const getPostFromDatabase: (slug: string) => {
title: string;
content: string;
}
getPostFromDatabase(params: Record<string, any>The parameters of the current route - e.g. for a route like /blog/[slug], a { slug: string } object.
params.slug);
if (const post: {
title: string;
content: string;
}
post) {
return const post: {
title: string;
content: string;
}
post;
}
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(404, 'Not found');
};クライアントサイドナビゲーション中は、SvelteKit はサーバーからこのデータを読み込みます。つまり、その戻り値は devalue によってシリアライズできなければならないということです。この API の詳細については load をご参照ください。
+page.js のように、+page.server.js は page options (prerender、ssr、csr) をエクスポートできます。
また、+page.server.js ファイルは actions をエクスポートできます。load がサーバーからデータを読み取る場合、actions は <form> 要素を使用してサーバーにデータを書き込むことができます。これらの使い方を学ぶには、form actions セクションをご参照ください。
+error
load 中にエラーが発生した場合、SvelteKit はデフォルトのエラーページをレンダリングします。+error.svelte を追加することで、ルート(route) ごとにエラーページをカスタマイズすることができます:
<script>
import { page } from '$app/state';
</script>
<h1>{page.status}: {page.error.message}</h1><script lang="ts">
import { page } from '$app/state';
</script>
<h1>{page.status}: {page.error.message}</h1>Legacy mode
$app/statewas added in SvelteKit 2.12. If you’re using an earlier version or are using Svelte 4, use$app/storesinstead.
SvelteKit は、ツリーを上がって (walk up the tree) 最も近いエラー境界 (error boundary) を探します — もし上記のファイルが存在しない場合は、デフォルトのエラーページをレンダリングする前に src/routes/blog/+error.svelte を探しに行き、その次に src/routes/+error.svelte を探します。もしそれも失敗した場合は (または、最上位の +error の ‘上に’ 位置する最上位の +layout の load 関数からエラーがスローされた場合)、SvelteKit は静的なフォールバックエラーページをレンダリングします。これは src/error.html ファイルを作成することでカスタマイズ可能です。
+layout(.server).js の load 関数の内側でエラーが発生した場合、ツリーの中で最も近くにあるエラー境界はそのレイアウトの上位にある +error.svelte ファイルです (隣ではありません)。
ルート(route)が見つからない場合 (404)、src/routes/+error.svelte (または、もしこのファイルが存在しない場合はデフォルトのエラーページ) が使われます。
エラーが
handleの内側や +server.js リクエストハンドラ の内側で発生した場合は、+error.svelteは使用されません。
エラーハンドリングに関する詳細は こちら からお読み頂けます。
+layout
これまで、ページを完全に独立したコンポーネントとして扱ってきました — ナビゲーションを行うと、既存の +page.svelte コンポーネントが破棄され、新しいページコンポーネントで置き換えられます。
しかし多くのアプリでは、トップレベルのナビゲーションやフッターのように 全ての ページで表示されるべき要素があります。全ての +page.svelte にそれらを繰り返し配置する代わりに、レイアウト(layouts) に配置することができます。
+layout.svelte
全てのページに適用するレイアウトを作成するには、src/routes/+layout.svelte というファイルを作成します。デフォルトのレイアウト (あなたが作成していない場合に SvelteKit が使用するもの) は以下のようなものです…
<script>
let { children } = $props();
</script>
{@render children()}…しかし、お望みのマークアップ(markup)、スタイル(styles)、動作(behaviour)を追加することができます。唯一の要求事項は、コンポーネントにページコンテンツのための @render タグを含めることです。例えば、nav bar を追加してみましょう:
<script>
let { children } = $props();
</script>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
{@render children()}<script lang="ts">
let { children } = $props();
</script>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/settings">Settings</a>
</nav>
{@render children()}/、/about、/settings のためのページを作成する場合…
<h1>Home</h1><h1>About</h1><h1>Settings</h1>… nav は常に表示され、3つのページのための a 要素をそれぞれクリックしても <h1> が置き換わるだけです。
レイアウトは ネスト させることができます。例えば、単一の /settings ページだけでなく、/settings/profile や /settings/notifications のような共有のサブメニューを持つネストしたページがあるとします (実例としては、github.com/settings をご参照ください)。
/settings 配下のページにのみ適用されるレイアウトを作成することができます (トップレベルの nav を持つ最上位のレイアウト(root layout)を継承しています):
<script>
/** @type {import('./$types').LayoutProps} */
let { data, children } = $props();
</script>
<h1>Settings</h1>
<div class="submenu">
{#each data.sections as section}
<a href="/settings/{section.slug}">{section.title}</a>
{/each}
</div>
{@render children()}<script lang="ts">
import type { LayoutProps } from './$types';
let { data, children }: LayoutProps = $props();
</script>
<h1>Settings</h1>
<div class="submenu">
{#each data.sections as section}
<a href="/settings/{section.slug}">{section.title}</a>
{/each}
</div>
{@render children()}Legacy mode
LayoutPropsは 2.16.0 で追加されました。以前のバージョンでは、代わりにプロパティを手動で型付けする必要がありました。
data がどのように入力されるかは、すぐ下の次のセクションにある +layout.js の例を見ればわかります。
デフォルトでは、各レイアウトはその上にあるレイアウトを継承します。そうしたくない場合は、advanced layouts が役に立つでしょう。
+layout.js
+page.svelte が +page.js からデータを読み込むように、+layout.svelte コンポーネントは +layout.js の load 関数からデータを取得することができます。
/** @type {import('./$types').LayoutLoad} */
export function function load(): {
sections: {
slug: string;
title: string;
}[];
}
load() {
return {
sections: {
slug: string;
title: string;
}[]
sections: [
{ slug: stringslug: 'profile', title: stringtitle: 'Profile' },
{ slug: stringslug: 'notifications', title: stringtitle: 'Notifications' }
]
};
}import type { type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutLoad } from './$types';
export const const load: LayoutLoadload: type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
type LayoutLoad = (event: Kit.LoadEvent<Record<string, any>, Record<string, any> | null, Record<string, any>, string | null>) => MaybePromise<void | Record<string, any>>
LayoutLoad = () => {
return {
sections: {
slug: string;
title: string;
}[]
sections: [
{ slug: stringslug: 'profile', title: stringtitle: 'Profile' },
{ slug: stringslug: 'notifications', title: stringtitle: 'Notifications' }
]
};
};+layout.js が page options (prerender、ssr、csr) をエクスポートする場合、それは子ページのデフォルトとしても使用されます。
レイアウトの load 関数から返されるデータは全ての子ページで利用することができます:
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script><script lang="ts">
import type { PageProps } from './$types';
let { data }: PageProps = $props();
console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script>しばしば、ページ間を移動しているときにレイアウトデータが変更されないことがあります。SvelteKit は必要に応じてインテリジェントに
load関数を再実行します。
+layout.server.js
サーバー上でレイアウトの load 関数を実行するためには、それを +layout.server.js に移動し、LayoutLoad 型を LayoutServerLoad に変更します。
+layout.js と同様に、+layout.server.js では page options — prerender、ssr、csr をエクスポートすることができます。
+server
ページと同様に、+server.js ファイルを使うことで (よく ‘API ルート(API route)’ または ‘エンドポイント(endpoint)’ とも呼ばれる) ルート(routes) を定義でき、これによってレスポンスを完全にコントロールすることができます。+server.js ファイル は GET、POST、PATCH、PUT、DELETE、OPTIONS、HEAD といった HTTP verbs に対応する関数をエクスポートします。これは RequestEvent を引数に取り、Response オブジェクトを返します。
例えば、GET ハンドラを使用した /api/random-number ルート(route)を作成できます:
import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export function function GET({ url }: {
url: any;
}): Response
GET({ url: anyurl }) {
const const min: numbermin = var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number(url: anyurl.searchParams.get('min') ?? '0');
const const max: numbermax = var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number(url: anyurl.searchParams.get('max') ?? '1');
const const d: numberd = const max: numbermax - const min: numbermin;
if (function isNaN(number: number): booleanReturns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
isNaN(const d: numberd) || const d: numberd < 0) {
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(400, 'min and max must be numbers, and min must be less than max');
}
const const random: numberrandom = const min: numbermin + var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.random(): numberReturns a pseudorandom number between 0 and 1.
random() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => ResponseThis Fetch API interface represents the response to a request.
Response(var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
String(const random: numberrandom));
}import { function error(status: number, body: App.Error): never (+1 overload)Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error } from '@sveltejs/kit';
import type { type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler } from './$types';
export const const GET: RequestHandlerGET: type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler = ({ url: URLThe requested URL.
url }) => {
const const min: numbermin = var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number(url: URLThe requested URL.
url.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | nullReturns the first value associated to the given search parameter.
get('min') ?? '0');
const const max: numbermax = var Number: NumberConstructor
(value?: any) => number
An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.
Number(url: URLThe requested URL.
url.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | nullReturns the first value associated to the given search parameter.
get('max') ?? '1');
const const d: numberd = const max: numbermax - const min: numbermin;
if (function isNaN(number: number): booleanReturns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
isNaN(const d: numberd) || const d: numberd < 0) {
function error(status: number, body?: {
message: string;
} extends App.Error ? App.Error | string | undefined : never): never (+1 overload)
Throws an error with a HTTP status code and an optional message.
When called during request handling, this will cause SvelteKit to
return an error response without invoking handleError.
Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.
error(400, 'min and max must be numbers, and min must be less than max');
}
const const random: numberrandom = const min: numbermin + var Math: MathAn intrinsic object that provides basic mathematics functionality and constants.
Math.Math.random(): numberReturns a pseudorandom number between 0 and 1.
random() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => ResponseThis Fetch API interface represents the response to a request.
Response(var String: StringConstructor
(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
String(const random: numberrandom));
};Response の第一引数には ReadableStream を指定することができ、大量のデータをストリームしたり、server-sent events を作成したりすることができます (AWS Lambda のような、レスポンスをバッファするプラットフォームにデプロイする場合は除きます)。
便宜上、@sveltejs/kit の error、redirect、json メソッドを使用することは可能です (ただし、使用する必要はありません)。
エラーがスローされる場合 (error(...) の場合でも、予期せぬエラーの場合でもどちらでも)、レスポンスは Accept ヘッダーに応じて、そのエラーの JSON 表現か、src/error.html でカスタマイズすることができるフォールバックエラーページとなります。この場合、+error.svelte コンポーネントはレンダリングされません。エラーハンドリングに関する詳細は こちら からお読み頂けます。
OPTIONSハンドラを作成する場合、Vite がAccess-Control-Allow-OriginヘッダーとAccess-Control-Allow-Methodsヘッダーを注入することにご注意ください。本番環境では、あなたが明示的に追加しない限り注入されないはずです。
+layoutファイルは+server.jsファイルに影響を与えません。各リクエストの前になんらかのロジックを実行したい場合は、サーバーのhandleフックに追加してください。
Receiving data
+server.js ファイルは、POST / PUT/PATCH/DELETE/OPTIONS/HEAD ハンドラをエクスポートすることで、完全な API を作成することができます:
<script>
let a = 0;
let b = 0;
let total = 0;
async function add() {
const response = await fetch('/api/add', {
method: 'POST',
body: JSON.stringify({ a, b }),
headers: {
'content-type': 'application/json'
}
});
total = await response.json();
}
</script>
<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}
<button onclick={add}>Calculate</button><script lang="ts">
let a = 0;
let b = 0;
let total = 0;
async function add() {
const response = await fetch('/api/add', {
method: 'POST',
body: JSON.stringify({ a, b }),
headers: {
'content-type': 'application/json'
}
});
total = await response.json();
}
</script>
<input type="number" bind:value={a}> +
<input type="number" bind:value={b}> =
{total}
<button onclick={add}>Calculate</button>import { function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function function POST({ request }: {
request: any;
}): Promise<Response>
POST({ request: anyrequest }) {
const { const a: anya, const b: anyb } = await request: anyrequest.json();
return function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json(const a: anya + const b: anyb);
}import { function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json } from '@sveltejs/kit';
import type { type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler } from './$types';
export const const POST: RequestHandlerPOST: type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler = async ({ request: RequestThe original request object.
request }) => {
const { const a: anya, const b: anyb } = await request: RequestThe original request object.
request.Body.json(): Promise<any>json();
return function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json(const a: anya + const b: anyb);
};一般的には、ブラウザからサーバーにデータを送信する方法としては form actions のほうがより良い方法です。
GETハンドラがエクスポートされている場合、HEADリクエストはGETハンドラのレスポンスボディのcontent-lengthを返します。
Fallback method handler
fallback ハンドラをエクスポートすると、ハンドリングされていないリクエスト (+server.js にそれ専用のエクスポートがない MOVE などのメソッドを含む) にマッチします。
import { function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json, function text(body: string, init?: ResponseInit): ResponseCreate a Response object from the supplied body.
text } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export async function function POST({ request }: {
request: any;
}): Promise<Response>
POST({ request: anyrequest }) {
const { const a: anya, const b: anyb } = await request: anyrequest.json();
return function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json(const a: anya + const b: anyb);
}
// This handler will respond to PUT, PATCH, DELETE, etc.
/** @type {import('./$types').RequestHandler} */
export async function function fallback({ request }: {
request: any;
}): Promise<Response>
fallback({ request: anyrequest }) {
return function text(body: string, init?: ResponseInit): ResponseCreate a Response object from the supplied body.
text(`I caught your ${request: anyrequest.method} request!`);
}import { function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json, function text(body: string, init?: ResponseInit): ResponseCreate a Response object from the supplied body.
text } from '@sveltejs/kit';
import type { type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler } from './$types';
export const const POST: RequestHandlerPOST: type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler = async ({ request: RequestThe original request object.
request }) => {
const { const a: anya, const b: anyb } = await request: RequestThe original request object.
request.Body.json(): Promise<any>json();
return function json(data: any, init?: ResponseInit): ResponseCreate a JSON Response object from the supplied data.
json(const a: anya + const b: anyb);
};
// This handler will respond to PUT, PATCH, DELETE, etc.
export const const fallback: RequestHandlerfallback: type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
type RequestHandler = (event: Kit.RequestEvent<Record<string, any>, string | null>) => MaybePromise<Response>
RequestHandler = async ({ request: RequestThe original request object.
request }) => {
return function text(body: string, init?: ResponseInit): ResponseCreate a Response object from the supplied body.
text(`I caught your ${request: RequestThe original request object.
request.Request.method: stringReturns request’s HTTP method, which is “GET” by default.
method} request!`);
};
HEADリクエストの場合、fallbackハンドラよりGETハンドラが優先されます。
Content negotiation
+server.js ファイルは +page ファイルと同じディレクトリに置くことができ、これによって同じルート(route)がページにも API エンドポイントにもなるようにすることができます。これがどちらなのか判断するために、SvelteKit は以下のルールを適用します:
PUT/PATCH/DELETE/OPTIONSリクエストは、ページには適用されないため、常に+server.jsで処理されます。GET/POST/HEADリクエストは、acceptヘッダーがtext/htmlを優先している場合 (言い換えると、ブラウザのページリクエストの場合)、ページリクエストとして扱われます。それ以外の場合は+server.jsで処理されます。GETリクエストに対するレスポンスにはVary: Acceptヘッダーが含まれるため、プロキシーやブラウザは HTML と JSON のレスポンスを別々にキャッシュします。
$types
これまでの例を通してずっと、$types.d.ts ファイルからインポートしてきました。これは、TypeScript (または JavaScript を JSDoc の型アノテーションと) 使用している場合に最上位のファイル(root files)を扱う際に型の安全性をもたらすために SvelteKit が隠しディレクトリに作成するファイルです。
例えば、let { data } = $props() に PageProps (または +layout.svelte ファイルの場合は LayoutProps) アノテーションを付けると、data の型は load の戻り値であると TypeScript に伝えることができます:
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script><script lang="ts">
import type { PageProps } from './$types';
let { data }: PageProps = $props();
</script>2.16.0 で追加された
PagePropsとLayoutProps型は、dataprop をPageDataまたはLayoutDataとして型付けするためのショートカットです。また、ページのformやレイアウトのchildrenなどの他の props についても型付けできます。以前のバージョンでは、これらのプロパティを手動で型付けする必要がありました。例えば、ページの場合:+page/** @type {{ data: import('./$types').PageData, form: import('./$types').ActionData }} */ let {let data: anydata,let form: anyform } =function $props(): any namespace $props$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();import type {import PageDataPageData,import ActionDataActionData } from './$types'; let {let data: PageDatadata,let form: ActionDataform }: {data: PageDatadata:import PageDataPageData,form: ActionDataform:import ActionDataActionData } =function $props(): any namespace $props$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();または、レイアウトの場合:
+layout/** @type {{ data: import('./$types').LayoutData, children: Snippet }} */ let {let data: anydata,let children: anychildren } =function $props(): any namespace $props$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();import type {import LayoutDataLayoutData } from './$types'; let {let data: LayoutDatadata,let children: Snippetchildren }: {data: LayoutDatadata:import LayoutDataLayoutData,children: Snippetchildren:type Snippet = /*unresolved*/ anySnippet } =function $props(): any namespace $props$props();Declares the props that a component accepts. Example:
let { optionalProp = 42, requiredProp, bindableProp = $bindable() }: { optionalProp?: number; requiredProps: string; bindableProp: boolean } = $props();
load 関数に PageLoad、PageServerLoad、LayoutLoad、LayoutServerLoad (それぞれ +page.js、+page.server.js、+layout.js、+layout.server.js) というアノテーションを付けると、params と戻り値が正しく型付けされることが保証されます。
VS Code や、language server protocol と TypeScript plugin をサポートする IDE を使用している場合は、これらの型を 完全に 省略することができます! Svelte の IDE ツール類があなたのために正しい型を挿入してくれるので、あなたはご自身で型を書くことなく型チェックすることができます。これはコマンドラインツール svelte-check でも機能します。
$types の省略については、私たちのブログ記事でより詳細な情報をお読み頂けます。
その他のファイル
ルート(route)ディレクトリ内のその他のファイルは SvelteKit から無視されます。つまり、コンポーネントやユーティリティモジュールを、それらを必要とするルート(routes)に配置することができます。
コンポーネントやモジュールが複数のルート(routes)から必要な場合、$lib にそれらを配置すると良いでしょう。
その他の参考資料
Edit this page on GitHub llms.txt