Skip to main content

ルーティング

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)には + という接頭辞が付いているので、それで見分けることができます。

We’ll introduce these files in a moment in more detail, but here are a few simple rules to help you remember how SvelteKit’s routing works:

  • All files can run on the server
  • All files run on the client except +server files
  • +layout and +error files apply to subdirectories as well as the directory they live in

+page

+page.svelte

+page.svelte コンポーネントはアプリのページを定義します。デフォルトでは、ページは最初のリクエストではサーバー (SSR) でレンダリングされ、その後のナビゲーションではブラウザ (CSR) でレンダリングされます。

src/routes/+page
<h1>Hello and welcome to my site!</h1>
<a href="/about">About my site</a>
src/routes/about/+page
<h1>About this site</h1>
<p>TODO...</p>
<a href="/">Home</a>

Pages can receive data from load functions via the data prop.

src/routes/blog/[slug]/+page
<script>
	/** @type {{ data: import('./$types').PageData }} */
	let { data } = $props();
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>
<script lang="ts">
	import type { PageData } from './$types';

	let { data }: { data: PageData } = $props();
</script>

<h1>{data.title}</h1>
<div>{@html data.content}</div>
Legacy mode

Svelte 4 では、代わりに export let data を使用します

SvelteKit では、ルート(routes)間のナビゲーションに、フレームワーク固有の <Link> コンポーネントではなく、<a> 要素を使用します。

+page.js

ページではたびたび、レンダリングの前になんらかのデータを読み込む必要があります。これに対応するため、load 関数をエクスポートする +page.js モジュールを追加しています:

src/routes/blog/[slug]/+page
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
/** @type {import('./$types').PageLoad} */ export function
function load({ params }: {
    params: any;
}): {
    title: string;
    content: string;
}
@type{import('./$types').PageLoad}
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
};

この関数は +page.svelte とともに実行されます。サーバーサイドレンダリング中はサーバーで実行され、クライアントサイドナビゲーション中はブラウザで実行されます。API の詳細は load をご参照ください。

+page.js では、load だけでなくページの動作(behaviour)を設定するための値をエクスポートすることができます:

  • export const prerender = true または false または 'auto'
  • export const ssr = true または false
  • export const csr = true または false

これらに関するより詳しい情報は page options をご覧ください。

+page.server.js

load 関数をサーバー上でのみ実行できるようにしたい場合 — 例えば、データベースからデータを取得したり、API キーのようなプライベートな環境変数にアクセスしたりする必要がある場合 — +page.js+page.server.js にリネームし、PageLoad 型を PageServerLoad に変更します。

src/routes/blog/[slug]/+page.server
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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>>
@type{import('./$types').PageServerLoad}
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(404, 'Not found');
};

クライアントサイドナビゲーション中は、SvelteKit はサーバーからこのデータを読み込みます。つまり、その戻り値は devalue によってシリアライズできなければならないということです。この API の詳細については load をご参照ください。

+page.js のように、+page.server.jspage options (prerenderssrcsr) をエクスポートできます。

また、+page.server.js ファイルは actions をエクスポートできます。load がサーバーからデータを読み取る場合、actions<form> 要素を使用してサーバーにデータを書き込むことができます。これらの使い方を学ぶには、form actions セクションをご参照ください。

+error

load 中にエラーが発生した場合、SvelteKit はデフォルトのエラーページをレンダリングします。+error.svelte を追加することで、ルート(route) ごとにエラーページをカスタマイズすることができます:

src/routes/blog/[slug]/+error
<script>
	import { page } from '$app/stores';
</script>

<h1>{$page.status}: {$page.error.message}</h1>

SvelteKit は、ツリーを上がって (walk up the tree) 最も近いエラー境界 (error boundary) を探します — もし上記のファイルが存在しない場合は、デフォルトのエラーページをレンダリングする前に src/routes/blog/+error.svelte を探しに行き、その次に src/routes/+error.svelte を探します。もしそれも失敗した場合は (または、最上位の +error の ‘上に’ 位置する最上位の +layoutload 関数からエラーがスローされた場合)、SvelteKit は静的なフォールバックエラーページをレンダリングします。これは src/error.html ファイルを作成することでカスタマイズ可能です。

+layout(.server).jsload 関数の内側でエラーが発生した場合、ツリーの中で最も近くにあるエラー境界はそのレイアウトの上位にある +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 を追加してみましょう:

<!- file: src/routes/+layout.svelte >
<script>
	let { children } = $props();
</script>

<nav>
	<a href="/">Home</a>
	<a href="/about">About</a>
	<a href="/settings">Settings</a>
</nav>

{@render children()}

//about/settings のためのページを作成する場合…

src/routes/+page
<h1>Home</h1>
src/routes/about/+page
<h1>About</h1>
src/routes/settings/+page
<h1>Settings</h1>

… nav は常に表示され、3つのページのための a 要素をそれぞれクリックしても <h1> が置き換わるだけです。

レイアウトは ネスト させることができます。例えば、単一の /settings ページだけでなく、/settings/profile/settings/notifications のような共有のサブメニューを持つネストしたページがあるとします (実例としては、github.com/settings をご参照ください)。

/settings 配下のページにのみ適用されるレイアウトを作成することができます (トップレベルの nav を持つ最上位のレイアウト(root layout)を継承しています):

src/routes/settings/+layout
<script>
	/** @type {{ data: import('./$types').LayoutData, children: import('svelte').Snippet }} */
	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 { LayoutData } from './$types';
	import type { Snippet } from 'svelte';

	let { data, children }: { data: LayoutData, children: Snippet } = $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()}

data がどのように入力されるかは、すぐ下の次のセクションにある +layout.js の例を見ればわかります。

デフォルトでは、各レイアウトはその上にあるレイアウトを継承します。そうしたくない場合は、advanced layouts が役に立つでしょう。

+layout.js

+page.svelte+page.js からデータを読み込むように、+layout.svelte コンポーネントは +layout.jsload 関数からデータを取得することができます。

src/routes/settings/+layout
/** @type {import('./$types').LayoutLoad} */
export function 
function load(): {
    sections: {
        slug: string;
        title: string;
    }[];
}
@type{import('./$types').LayoutLoad}
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.jspage options (prerenderssrcsr) をエクスポートする場合、それは子ページのデフォルトとしても使用されます。

レイアウトの load 関数から返されるデータは全ての子ページで利用することができます:

src/routes/settings/profile/+page
<script>
	/** @type {{ data: import('./$types').PageData }} */
	let { data } = $props();

	console.log(data.sections); // [{ slug: 'profile', title: 'Profile' }, ...]
</script>
<script lang="ts">
	import type { PageData } from './$types';

	let { data }: { data: PageData } = $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 optionsprerenderssrcsr をエクスポートすることができます。

+server

ページと同様に、+server.js ファイル (よく ‘API ルート(API route)’ または ‘エンドポイント(endpoint)’ とも呼ばれる) でルート(routes) を定義でき、これによってレスポンスを完全にコントロールすることができます。+server.js ファイル は GETPOSTPATCHPUTDELETEOPTIONSHEAD といった HTTP verbs に対応する関数をエクスポートします。これは RequestEvent を引数に取り、Response オブジェクトを返します。

例えば、GET ハンドラを使用した /api/random-number ルート(route)を作成できます:

src/routes/api/random-number/+server
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
} from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */ export function
function GET({ url }: {
    url: any;
}): Response
@type{import('./$types').RequestHandler}
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): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).

@paramnumber A numeric value.
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(400, 'min and max must be numbers, and min must be less than max');
} const const random: numberrandom = const min: numbermin + var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response

This Fetch API interface represents the response to a request.

MDN Reference

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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
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: URL

The 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: URL

The requested URL.

url
.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | null

Returns the first value associated to the given search parameter.

MDN Reference

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: URL

The requested URL.

url
.URL.searchParams: URLSearchParamssearchParams.URLSearchParams.get(name: string): string | null

Returns the first value associated to the given search parameter.

MDN Reference

get
('max') ?? '1');
const const d: numberd = const max: numbermax - const min: numbermin; if (function isNaN(number: number): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).

@paramnumber A numeric value.
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.

@paramstatus The HTTP status code. Must be in the range 400-599.
@parambody An object that conforms to the App.Error type. If a string is passed, it will be used as the message property.
@throwsHttpError This error instructs SvelteKit to initiate HTTP error handling.
@throwsError If the provided status is invalid (not between 400 and 599).
error
(400, 'min and max must be numbers, and min must be less than max');
} const const random: numberrandom = const min: numbermin + var Math: Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
() * const d: numberd;
return new var Response: new (body?: BodyInit | null, init?: ResponseInit) => Response

This Fetch API interface represents the response to a request.

MDN Reference

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/kiterrorredirectjson メソッドを使用することは可能です (ただし、使用する必要はありません)。

エラーがスローされる場合 (error(...) の場合でも、予期せぬエラーの場合でもどちらでも)、レスポンスは Accept ヘッダーに応じて、そのエラーの JSON 表現か、src/error.html でカスタマイズすることができるフォールバックエラーページとなります。この場合、+error.svelte コンポーネントはレンダリングされません。エラーハンドリングに関する詳細は こちら からお読み頂けます。

OPTIONS ハンドラを作成する場合、Vite が Access-Control-Allow-Origin ヘッダーと Access-Control-Allow-Methods ヘッダーを注入することにご注意ください。本番環境では、あなたが明示的に追加しない限り注入されないはずです。

Receiving data

+server.js ファイルは、POST / PUT/PATCH/DELETE/OPTIONS/HEAD ハンドラをエクスポートすることで、完全な API を作成することができます:

src/routes/add/+page
<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 on:click={add}>Calculate</button>
src/routes/api/add/+server
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
} from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */ export async function
function POST({ request }: {
    request: any;
}): Promise<Response>
@type{import('./$types').RequestHandler}
POST
({ request: anyrequest }) {
const { const a: anya, const b: anyb } = await request: anyrequest.json(); return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
}
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
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: Request

The original request object

request
}) => {
const { const a: anya, const b: anyb } = await request: Request

The original request object

request
.Body.json(): Promise<any>json();
return function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
(const a: anya + const b: anyb);
};

一般的には、ブラウザからサーバーにデータを送信する方法としては form actions のほうがより良い方法です。

GET ハンドラがエクスポートされている場合、HEAD リクエストは GET ハンドラのレスポンスボディの content-length を返します。

Fallback method handler

fallback ハンドラをエクスポートすると、ハンドリングされていないリクエスト (+server.js にそれ専用のエクスポートがない MOVE などのメソッドを含む) にマッチします。

src/routes/api/add/+server
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
, function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
} from '@sveltejs/kit';
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 | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
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>
@type{import('./$types').RequestHandler}
fallback
({ request: anyrequest }) {
return function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
(`I caught your ${request: anyrequest.method} request!`);
}
import { function json(data: any, init?: ResponseInit | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
json
, function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
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 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 | undefined): Response

Create a JSON Response object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such as status and headers that will be added to the response. Content-Type: application/json and Content-Length headers will be added automatically.
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: Request

The original request object

request
}) => {
return function text(body: string, init?: ResponseInit | undefined): Response

Create a Response object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such as status and headers that will be added to the response. A Content-Length header will be added automatically.
text
(`I caught your ${request: Request

The original request object

request
.Request.method: string

Returns request’s HTTP method, which is “GET” by default.

MDN Reference

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()PageData (または LayoutData の場合は +layout.svelte ファイル) にアノテーションを付けると、data の型は load の戻り値であると TypeScript に伝えることができます:

src/routes/blog/[slug]/+page
<script>
	/** @type {{ data: import('./$types').PageData }} */
	let { data } = $props();
</script>
<script lang="ts">
	import type { PageData } from './$types';

	let { data }: { data: PageData } = $props();
</script>

load 関数に PageLoadPageServerLoadLayoutLoadLayoutServerLoad (それぞれ +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