Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
SvelteKitCore concepts

Routing

At the heart of SvelteKit is afilesystem-based router. The routes of your app — i.e. the URL paths that users can access — are defined by the directories in your codebase:

  • src/routes is the root route
  • src/routes/about creates an/about route
  • src/routes/blog/[slug] creates a route with aparameter,slug, that can be used to load data dynamically when a user requests a page like/blog/hello-world

You can changesrc/routes to a different directory by editing theproject config.

Each route directory contains one or moreroute files, which can be identified by their+ prefix.

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

A+page.svelte component defines a page of your app. By default, pages are rendered both on the server (SSR) for the initial request and in the browser (CSR) for subsequent navigation.

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

SvelteKit uses<a> elements to navigate between routes, rather than a framework-specific<Link> component.

Pages can receive data fromload functions via thedata prop.

src/routes/blog/[slug]/+page
<script>/**@type{import('./$types').PageProps}*/let{ data }=$props();</script><h1>{data.title}</h1><div>{@htmldata.content}</div>
<scriptlang="ts">importtype{ PageProps }from'./$types';let{ data }:PageProps=$props();</script><h1>{data.title}</h1><div>{@htmldata.content}</div>
Legacy mode

PageProps was added in 2.16.0. In earlier versions, you had to type thedata property manually withPageData instead, see$types.

In Svelte 4, you’d useexport let data instead.

+page.js

Often, a page will need to load some data before it can be rendered. For this, we add a+page.js module that exports aload function:

src/routes/blog/[slug]/+page
import{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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}*/exportfunction
functionload({ 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...'};}
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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';
importtype{
typePageLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>typePageLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>
PageLoad
}from'./$types';
exportconstconstload:PageLoadload:
typePageLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>typePageLoad=(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...'};}
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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');
};

This function runs alongside+page.svelte, which means it runs on the server during server-side rendering and in the browser during client-side navigation. Seeload for full details of the API.

As well asload,+page.js can export values that configure the page’s behaviour:

  • export const prerender = true orfalse or'auto'
  • export const ssr = true orfalse
  • export const csr = true orfalse

You can find more information about these inpage options.

+page.server.js

If yourload function can only run on the server — for example, if it needs to fetch data from a database or you need to access privateenvironment variables like API keys — then you can rename+page.js to+page.server.js and change thePageLoad type toPageServerLoad.

src/routes/blog/[slug]/+page.server
import{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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}*/exportasyncfunctionfunctionload(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
constpost:{title:string;content:string;}
post
=await
constgetPostFromDatabase:(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(
constpost:{title:string;content:string;}
post
) {
return
constpost:{title:string;content:string;}
post
;
}
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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';
importtype{typePageServerLoad=(event:ServerLoadEvent<Record<string,any>,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>PageServerLoad}from'./$types';exportconstconstload:PageServerLoadload:typePageServerLoad=(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
constpost:{title:string;content:string;}
post
=await
constgetPostFromDatabase:(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(
constpost:{title:string;content:string;}
post
) {
return
constpost:{title:string;content:string;}
post
;
}
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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');
};

During client-side navigation, SvelteKit will load this data from the server, which means that the returned value must be serializable usingdevalue. Seeload for full details of the API.

Like+page.js,+page.server.js can exportpage optionsprerender,ssr andcsr.

A+page.server.js file can also exportactions. Ifload lets you read data from the server,actions let you write datato the server using the<form> element. To learn how to use them, see theform actions section.

+error

If an error occurs duringload, SvelteKit will render a default error page. You can customise this error page on a per-route basis by adding an+error.svelte file:

src/routes/blog/[slug]/+error
<script>import{ page }from'$app/state';</script><h1>{page.status}: {page.error.message}</h1>
<scriptlang="ts">import{ page }from'$app/state';</script><h1>{page.status}: {page.error.message}</h1>
Legacy mode

$app/state was added in SvelteKit 2.12. If you’re using an earlier version or are using Svelte 4, use$app/stores instead.

SvelteKit will ‘walk up the tree’ looking for the closest error boundary — if the file above didn’t exist it would trysrc/routes/blog/+error.svelte and thensrc/routes/+error.svelte before rendering the default error page. Ifthat fails (or if the error was thrown from theload function of the root+layout, which sits ‘above’ the root+error), SvelteKit will bail out and render a static fallback error page, which you can customise by creating asrc/error.html file.

If the error occurs inside aload function in+layout(.server).js, the closest error boundary in the tree is an+error.svelte fileabove that layout (not next to it).

If no route can be found (404),src/routes/+error.svelte (or the default error page, if that file does not exist) will be used.

+error.svelte isnot used when an error occurs insidehandle or a+server.js request handler.

You can read more about error handlinghere.

+layout

So far, we’ve treated pages as entirely standalone components — upon navigation, the existing+page.svelte component will be destroyed, and a new one will take its place.

But in many apps, there are elements that should be visible onevery page, such as top-level navigation or a footer. Instead of repeating them in every+page.svelte, we can put them inlayouts.

+layout.svelte

To create a layout that applies to every page, make a file calledsrc/routes/+layout.svelte. The default layout (the one that SvelteKit uses if you don’t bring your own) looks like this...

<script>let{ children }=$props();</script>{@renderchildren()}

...but we can add whatever markup, styles and behaviour we want. The only requirement is that the component includes a@render tag for the page content. For example, let’s add a nav bar:

src/routes/+layout
<script>let{ children }=$props();</script><nav><ahref="/">Home</a><ahref="/about">About</a><ahref="/settings">Settings</a></nav>{@renderchildren()}
<scriptlang="ts">let{ children }=$props();</script><nav><ahref="/">Home</a><ahref="/about">About</a><ahref="/settings">Settings</a></nav>{@renderchildren()}

If we create pages for/,/about and/settings...

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

...the nav will always be visible, and clicking between the three pages will only result in the<h1> being replaced.

Layouts can benested. Suppose we don’t just have a single/settings page, but instead have nested pages like/settings/profile and/settings/notifications with a shared submenu (for a real-life example, seegithub.com/settings).

We can create a layout that only applies to pages below/settings (while inheriting the root layout with the top-level nav):

src/routes/settings/+layout
<script>/**@type{import('./$types').LayoutProps}*/let{ data,children }=$props();</script><h1>Settings</h1><divclass="submenu">{#eachdata.sectionsassection}<ahref="/settings/{section.slug}">{section.title}</a>{/each}</div>{@renderchildren()}
<scriptlang="ts">importtype{ LayoutProps }from'./$types';let{ data,children }:LayoutProps=$props();</script><h1>Settings</h1><divclass="submenu">{#eachdata.sectionsassection}<ahref="/settings/{section.slug}">{section.title}</a>{/each}</div>{@renderchildren()}
Legacy mode

LayoutProps was added in 2.16.0. In earlier versions, you had totype the properties manually instead.

You can see howdata is populated by looking at the+layout.js example in the next section just below.

By default, each layout inherits the layout above it. Sometimes that isn’t what you want - in this case,advanced layouts can help you.

+layout.js

Just like+page.svelte loading data from+page.js, your+layout.svelte component can get data from aload function in+layout.js.

src/routes/settings/+layout
/**@type{import('./$types').LayoutLoad}*/exportfunction
functionload():{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'}]};}
importtype{
typeLayoutLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>typeLayoutLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>
LayoutLoad
}from'./$types';
exportconstconstload:LayoutLoadload:
typeLayoutLoad=(event:Kit.LoadEvent<Record<string,any>,Record<string,any>|null,Record<string,any>,string|null>)=>MaybePromise<void|Record<string,any>>typeLayoutLoad=(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'}]};};

If a+layout.js exportspage optionsprerender,ssr andcsr — they will be used as defaults for child pages.

Data returned from a layout’sload function is also available to all its child pages:

src/routes/settings/profile/+page
<script>/**@type{import('./$types').PageProps}*/let{ data }=$props();console.log(data.sections);// [{ slug: 'profile', title: 'Profile' }, ...]</script>
<scriptlang="ts">importtype{ PageProps }from'./$types';let{ data }:PageProps=$props();console.log(data.sections);// [{ slug: 'profile', title: 'Profile' }, ...]</script>

Often, layout data is unchanged when navigating between pages. SvelteKit will intelligently rerunload functions when necessary.

+layout.server.js

To run your layout’sload function on the server, move it to+layout.server.js, and change theLayoutLoad type toLayoutServerLoad.

Like+layout.js,+layout.server.js can exportpage optionsprerender,ssr andcsr.

+server

As well as pages, you can define routes with a+server.js file (sometimes referred to as an ‘API route’ or an ‘endpoint’), which gives you full control over the response. Your+server.js file exports functions corresponding to HTTP verbs likeGET,POST,PATCH,PUT,DELETE,OPTIONS, andHEAD that take aRequestEvent argument and return aResponse object.

For example we could create an/api/random-number route with aGET handler:

src/routes/api/random-number/+server
import{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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}*/exportfunction
functionGET({ url }:{url:any;}):Response
@type{import('./$types').RequestHandler}
GET
({url:anyurl}) {
constconstmin:numbermin=
varNumber: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');
constconstmax:numbermax=
varNumber: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');
constconstd:numberd=constmax:numbermax-constmin:numbermin;if(functionisNaN(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
(constd:numberd)||constd:numberd<0) {
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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');
}constconstrandom:numberrandom=constmin:numbermin+varMath:Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
()*constd:numberd;
returnnewvarResponse:new(body?:BodyInit|null,init?:ResponseInit)=>Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
(
varString:StringConstructor(value?:any)=>string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

String
(constrandom:numberrandom));
}
import{functionerror(status:number,body:App.Error):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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';
importtype{
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
}from'./$types';
exportconstconstGET:RequestHandlerGET:
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
=({url:URL

The requested URL.

url
})=>{
constconstmin:numbermin=
varNumber: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');
constconstmax:numbermax=
varNumber: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');
constconstd:numberd=constmax:numbermax-constmin:numbermin;if(functionisNaN(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
(constd:numberd)||constd:numberd<0) {
functionerror(status:number,body?:{message:string;}extendsApp.Error?App.Error|string|undefined:never):never(+1overload)

Throws an error with a HTTP status code and an optional message.When called during request handling, this will cause SvelteKit toreturn an error response without invokinghandleError.Make sure you’re not catching the thrown error, which would prevent SvelteKit from handling it.

@paramstatus TheHTTP 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');
}constconstrandom:numberrandom=constmin:numbermin+varMath:Math

An intrinsic object that provides basic mathematics functionality and constants.

Math
.Math.random(): number

Returns a pseudorandom number between 0 and 1.

random
()*constd:numberd;
returnnewvarResponse:new(body?:BodyInit|null,init?:ResponseInit)=>Response

This Fetch API interface represents the response to a request.

MDN Reference

Response
(
varString:StringConstructor(value?:any)=>string

Allows manipulation and formatting of text strings and determination and location of substrings within strings.

String
(constrandom:numberrandom));
};

The first argument toResponse can be aReadableStream, making it possible to stream large amounts of data or create server-sent events (unless deploying to platforms that buffer responses, like AWS Lambda).

You can use theerror,redirect andjson methods from@sveltejs/kit for convenience (but you don’t have to).

If an error is thrown (eithererror(...) or an unexpected error), the response will be a JSON representation of the error or a fallback error page — which can be customised viasrc/error.html — depending on theAccept header. The+error.svelte component willnot be rendered in this case. You can read more about error handlinghere.

When creating anOPTIONS handler, note that Vite will injectAccess-Control-Allow-Origin andAccess-Control-Allow-Methods headers — these will not be present in production unless you add them.

+layout files have no effect on+server.js files. If you want to run some logic before each request, add it to the serverhandle hook.

Receiving data

By exportingPOST /PUT/PATCH/DELETE/OPTIONS/HEAD handlers,+server.js files can be used to create a complete API:

src/routes/add/+page
<script>leta=0;letb=0;lettotal=0;asyncfunctionadd() {constresponse=awaitfetch('/api/add',{method:'POST',body:JSON.stringify({ a,b }),headers:{'content-type':'application/json'}});total=awaitresponse.json();}</script><inputtype="number"bind:value={a}> +<inputtype="number"bind:value={b}> ={total}<buttononclick={add}>Calculate</button>
<scriptlang="ts">leta=0;letb=0;lettotal=0;asyncfunctionadd() {constresponse=awaitfetch('/api/add',{method:'POST',body:JSON.stringify({ a,b }),headers:{'content-type':'application/json'}});total=awaitresponse.json();}</script><inputtype="number"bind:value={a}> +<inputtype="number"bind:value={b}> ={total}<buttononclick={add}>Calculate</button>
src/routes/api/add/+server
import{functionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
}from'@sveltejs/kit';
/**@type{import('./$types').RequestHandler}*/exportasyncfunction
functionPOST({ request }:{request:any;}):Promise<Response>
@type{import('./$types').RequestHandler}
POST
({request:anyrequest}) {
const{consta:anya,constb:anyb}=awaitrequest:anyrequest.json();returnfunctionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
(consta:anya+constb:anyb);
}
import{functionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
}from'@sveltejs/kit';
importtype{
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
}from'./$types';
exportconstconstPOST:RequestHandlerPOST:
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
=async({request:Request

The original request object.

request
})=>{
const{consta:anya,constb:anyb}=awaitrequest:Request

The original request object.

request
.Body.json():Promise<any>json();
returnfunctionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
(consta:anya+constb:anyb);
};

In general,form actions are a better way to submit data from the browser to the server.

If aGET handler is exported, aHEAD request will return thecontent-length of theGET handler’s response body.

Fallback method handler

Exporting thefallback handler will match any unhandled request methods, including methods likeMOVE which have no dedicated export from+server.js.

src/routes/api/add/+server
import{functionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
,functiontext(body:string,init?:ResponseInit):Response

Create aResponse object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such asstatus andheaders that will be added to the response. AContent-Length header will be added automatically.
text
}from'@sveltejs/kit';
/**@type{import('./$types').RequestHandler}*/exportasyncfunction
functionPOST({ request }:{request:any;}):Promise<Response>
@type{import('./$types').RequestHandler}
POST
({request:anyrequest}) {
const{consta:anya,constb:anyb}=awaitrequest:anyrequest.json();returnfunctionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
(consta:anya+constb:anyb);
}// This handler will respond to PUT, PATCH, DELETE, etc./**@type{import('./$types').RequestHandler}*/exportasyncfunction
functionfallback({ request }:{request:any;}):Promise<Response>
@type{import('./$types').RequestHandler}
fallback
({request:anyrequest}) {
returnfunctiontext(body:string,init?:ResponseInit):Response

Create aResponse object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such asstatus andheaders that will be added to the response. AContent-Length header will be added automatically.
text
(`I caught your${request:anyrequest.method}request!`);
}
import{functionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
,functiontext(body:string,init?:ResponseInit):Response

Create aResponse object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such asstatus andheaders that will be added to the response. AContent-Length header will be added automatically.
text
}from'@sveltejs/kit';
importtype{
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
}from'./$types';
exportconstconstPOST:RequestHandlerPOST:
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
=async({request:Request

The original request object.

request
})=>{
const{consta:anya,constb:anyb}=awaitrequest:Request

The original request object.

request
.Body.json():Promise<any>json();
returnfunctionjson(data:any,init?:ResponseInit):Response

Create a JSONResponse object from the supplied data.

@paramdata The value that will be serialized as JSON.
@paraminit Options such asstatus andheaders that will be added to the response.Content-Type: application/json andContent-Length headers will be added automatically.
json
(consta:anya+constb:anyb);
};// This handler will respond to PUT, PATCH, DELETE, etc.exportconstconstfallback:RequestHandlerfallback:
typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>typeRequestHandler=(event:Kit.RequestEvent<Record<string,any>,string|null>)=>MaybePromise<Response>
RequestHandler
=async({request:Request

The original request object.

request
})=>{
returnfunctiontext(body:string,init?:ResponseInit):Response

Create aResponse object from the supplied body.

@parambody The value that will be used as-is.
@paraminit Options such asstatus andheaders that will be added to the response. AContent-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!`);
};

ForHEAD requests, theGET handler takes precedence over thefallback handler.

Content negotiation

+server.js files can be placed in the same directory as+page files, allowing the same route to be either a page or an API endpoint. To determine which, SvelteKit applies the following rules:

  • PUT /PATCH/DELETE/OPTIONS requests are always handled by+server.js since they do not apply to pages
  • GET /POST/HEAD requests are treated as page requests if theaccept header prioritisestext/html (in other words, it’s a browser page request), else they are handled by+server.js.
  • Responses toGET requests will include aVary: Accept header, so that proxies and browsers cache HTML and JSON responses separately.

$types

Throughout the examples above, we’ve been importing types from a$types.d.ts file. This is a file SvelteKit creates for you in a hidden directory if you’re using TypeScript (or JavaScript with JSDoc type annotations) to give you type safety when working with your root files.

For example, annotatinglet { data } = $props() withPageProps (orLayoutProps, for a+layout.svelte file) tells TypeScript that the type ofdata is whatever was returned fromload:

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

ThePageProps andLayoutProps types, added in 2.16.0, are a shortcut for typing thedata prop asPageData orLayoutData, as well as other props, such asform for pages, orchildren for layouts. In earlier versions, you had to type these properties manually. For example, for a page:

+page
/**@type{{ data: import('./$types').PageData, form: import('./$types').ActionData }}*/let{letdata:anydata,letform:anyform}=
function$props():anynamespace$props

Declares the props that a component accepts. Example:

let{ optionalProp=42,requiredProp,bindableProp=$bindable() }:{ optionalProp?:number; requiredProps:string; bindableProp:boolean}=$props();

https://svelte.dev/docs/svelte/$props

$props
();
importtype{importPageDataPageData,importActionDataActionData}from'./$types';let{letdata:PageDatadata,letform:ActionDataform}:{data:PageDatadata:importPageDataPageData,form:ActionDataform:importActionDataActionData}=
function$props():anynamespace$props

Declares the props that a component accepts. Example:

let{ optionalProp=42,requiredProp,bindableProp=$bindable() }:{ optionalProp?:number; requiredProps:string; bindableProp:boolean}=$props();

https://svelte.dev/docs/svelte/$props

$props
();

Or, for a layout:

+layout
/**@type{{ data: import('./$types').LayoutData, children: Snippet }}*/let{letdata:anydata,letchildren:anychildren}=
function$props():anynamespace$props

Declares the props that a component accepts. Example:

let{ optionalProp=42,requiredProp,bindableProp=$bindable() }:{ optionalProp?:number; requiredProps:string; bindableProp:boolean}=$props();

https://svelte.dev/docs/svelte/$props

$props
();
importtype{importLayoutDataLayoutData}from'./$types';let{letdata:LayoutDatadata,letchildren:Snippetchildren}:{data:LayoutDatadata:importLayoutDataLayoutData,children:Snippetchildren:typeSnippet=/*unresolved*/anySnippet}=
function$props():anynamespace$props

Declares the props that a component accepts. Example:

let{ optionalProp=42,requiredProp,bindableProp=$bindable() }:{ optionalProp?:number; requiredProps:string; bindableProp:boolean}=$props();

https://svelte.dev/docs/svelte/$props

$props
();

In turn, annotating theload function withPageLoad,PageServerLoad,LayoutLoad orLayoutServerLoad (for+page.js,+page.server.js,+layout.js and+layout.server.js respectively) ensures thatparams and the return value are correctly typed.

If you’re using VS Code or any IDE that supports the language server protocol and TypeScript plugins then you can omit these typesentirely! Svelte’s IDE tooling will insert the correct types for you, so you’ll get type checking without writing them yourself. It also works with our command line toolsvelte-check.

You can read more about omitting$types in ourblog post about it.

Other files

Any other files inside a route directory are ignored by SvelteKit. This means you can colocate components and utility modules with the routes that need them.

If components and modules are needed by multiple routes, it’s a good idea to put them in$lib.

Further reading

Edit this page on GitHub llms.txt


[8]ページ先頭

©2009-2025 Movatter.jp