TutorialAdvanced SvelteKit
- Advanced routingParam matchers
irst, create a new file called src/params/hex.js and export a match function from it: export function match(value) { return /^[0Advanced routingOptional parametershow to create routes with dynamic parameters.Sometimes it's helpful to make a parameter optional. A classic example is when you uAdvanced routingRest parametersof path segments, use a [...rest] parameter, so named for its resemblance to rest parameters in JavaScript.Rename src/routes/[patAdvanced loadingInvalidationmezone]/+page.js to re-run because params.timezone is invalid. But the load function in src/routes/+layout.js does not re-run, becExamplesTransitions
ExamplesActions
TutorialBasic Svelte
- ActionsAdding parameters
Like transitions and animations, an action can take an argument, which the action function will be called with alongside the element it belongs to.InTransitionsAdding parametersTransition functions can accept parameters. Replace the fade transition with fly... <script> importTransitionsCustom CSS transitionsthe transition is applied, and any parameters that were passed in — and returns a transition object which can have the following pTutorialBasic SvelteKit
- RoutingRoute parameters
To create routes with dynamic parameters, use square brackets around a valid variable name. For examplAPI routesOther handlers.js'; export async function PUT({ params, request, cookies }) { const { done } = await request.json(); const userid = cookies.gLoading dataPage data/data.js'; export function load({ params }) { const post = posts.find((post) => post.slug === params.slug); return { post }DocsSvelteKit
- Reference@sveltejs/kitParamMatcher
The shape of a param matcher. See matching for more info. type ParamMatcher = (param: string) => booleAdvancedAdvanced routingRest parametersg.md would result in the following parameters being available to the page: { org: 'sveltejs', repo: 'kit', branch: 'main', fiAdvancedAdvanced routingOptional parametersA route like [lang]/home contains a parameter named lang which is required. Sometimes it's beneficialCore conceptsLoading dataUsing URL dataparamsparams is derived from url.pathname and route.id.Given a route.id of /a/[b]/[...c] and a url.pathnameAdvancedAdvanced routingRest parameters404 pagesRest parameters also allow you to render custom 404s. Given these routes...src/routes/ ├ marx-brothersGetting startedProject structurefiles] │ │ └ [your lib files] │ ├ params/ │ │ └ [your param matchers] │ ├ routes/ │ │ └ [your routes] │ ├ app.html │ ├ error.htmlBuild and deployWriting adaptersAPI, which creates an Adapter:/** @param {AdapterSpecificOptions} options */ export default function (options) { /** @type {imporCore conceptsLoading dataStreaming with promisesd} */ export async function load({ params }) { return { // make sure the `await` happens at the end, otherwise we // can't stReference@sveltejs/kitLoadEventnt directly. interface LoadEvent< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, Data extends Record<string, uReference@sveltejs/kitNavigationEventinterface NavigationEvent< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteIdReference@sveltejs/kitNavigationTargettion. interface NavigationTarget< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId |Reference@sveltejs/kitPagehe `$page` store. interface Page< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId |Reference@sveltejs/kitRequestEventinterface RequestEvent< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extReference@sveltejs/kitServerLoadEventinterface ServerLoadEvent< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentDaReferenceTypesGenerated typesndler and Load types both accept a Params argument allowing you to type the params object. For example this endpoint expects foo,Core conceptsLoading dataPage dataageLoad} */ export function load({ params }) { return { post: { title: `Title for ${params.slug} goes here`, content: `CoCore conceptsLoading dataRerunning load functionsd} */ export async function load({ params }) { return { post: await db.getPost(params.slug) }; }import * as db from '$lib/servAdvancedAdvanced routingMatchingnt that. You can ensure that route parameters are well-formed by adding a matcher — which takes the parameter string ("apple&AdvancedErrorsExpected errorsd} */ export async function load({ params }) { const post = await db.getPost(params.slug); if (!post) { error(404, { messaAppendixMigrating to SvelteKit v2`resolvePath` has been removedD (like /blog/[slug]) and a set of parameters (like { slug: 'hello' }) to a pathname. Unfortunately the return value didn't includReference$app/typesRouteParamsA utility for getting the parameters associated with a given route. type BlogParams = RouteParams<'/bReference$app/typesLayoutParamsA utility for getting the parameters associated with a given layout, which is similar to RouteParams bCore conceptsForm actionsNamed actionsinvoke a named action, add a query parameter with the name prefixed by a / character:<!--- file: src/routes/login/+page.svelte ---Core conceptsState managementStoring state in the URLrting rules on a table, URL search parameters (like ?sort=price&order=ascending) are a good place to put them. You can put theReference@sveltejs/kitLoadn using Load directly. type Load< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, InputData extends Record<striReference$app/pathsresolvey populating dynamic segments with parameters.During server rendering, the base path is relative and depends on the page currentlyReferenceConfigurationprerenderall routes containing no required [parameters] with optional parameters included as being empty (since SvelteKit doesn't know whaReference@sveltejs/kitActionor more information. type Action< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record<strReference@sveltejs/kitActionsr more information. type Actions< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record<strReference@sveltejs/kitRequestHandleruests with that method.It receives Params as the first generic argument, which you can skip by using generated types instead. typeReference@sveltejs/kitServerLoaderLoad directly. type ServerLoad< Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentData extends Record<strReference@sveltejs/kitAdapterEntrya Netlify _redirects file as /foo/:param, so they share an ID filter(route: RouteDefinition): boolean; A function that compares tReference$app/navigationinvalidatefetch or depends (including query parameters). To create a custom identifier, use a string beginning with [a-z]+: (e.g. custom:stReferenceConfigurationembedded% instead of window, and will pass params from the server rather than inferring them from location.pathname. Note that it is generCore conceptsLoading dataUsing `getRequestEvent`url.pathname + url.search; const params = new URLSearchParams({ redirectTo }); redirect(307, `/login?${params}`); } returnAppendixGlossaryPrerenderingthat is loaded based on the page's parameters as long as all users will be seeing the same prerendered content.Pre-rendered pagesReference@sveltejs/kitSubmitFunctiona form submission response. * @param options Set `reset: false` if you don't want the `<form>` values to be reset after a succReference$app/statepage/state'; const id = $derived(page.params.id); // This will correctly update id for usage on this page $: badId = page.params.id;ReferenceConfigurationfilesthroughout the codebase as $lib params?: string; undefined a directory containing parameter matchers routes?: string; undeCore conceptsRouting$typesrver.js respectively) ensures that params and the return value are correctly typed.If you're using VS Code or any IDE that supportCore conceptsLoading dataLayout datandIndex(post => post.slug === page.params.slug)); let next = $derived(data.posts[index + 1]);+++ </script> <h1>{data.post.titCore conceptsLoading dataMaking fetch requestsxport async function load({ fetch, params }) { const res = await fetch(`/api/items/${params.id}`); const item = await res.json()Core conceptsLoading dataUsing parent datarent(). Here, for example, getData(params) does not depend on the result of calling parent(), so we should call it first to avoidAppendixFrequently asked questionsHow do I use a different backend API server?tHandler} */ export function GET({ params, url }) { return fetch(`https://example.com/${params.path + url.search}`); }(Note thatReference@sveltejs/kitSSRManifesthers: () => Promise<Record<string, ParamMatcher>>; server_assets: Record<string, number>; A [file]: size map of all assetBuild and deployVercelIncremental Static RegenerationallowQueryA list of valid query parameters that contribute to the cache key. Other parameters (such as utm trackAdvancedHooksUniversal hooksreroutes used to select the route and its parameters.For example, you might have a src/routes/[[lang]]/about/+page.svelte page, which shoCore conceptsLoading dataUniversal vs serverInputproperties describing the request (params, route and url) and various functions (fetch, setHeaders, parent, depends and untrack).Core conceptsLoading dataRerunning load functionsWhen do load functions rerun?the following situations:undefined params and url can change in response to a <a href=".."> link click, a `<form>` interCore conceptsForm actionsProgressive enhancementCustom event listener/ let { form } = $props(); /** @param {SubmitEvent & { currentTarget: EventTarget & HTMLFormElement}} event */ async functionCore conceptsRemote functionsqueryQuery argumentst } from '../data.remote'; let { params } = $props(); const post = $derived(await getPost(params.slug)); </script> <h1>{post.Getting startedWeb standardsURL APIsURLSearchParamsounter a URL, you can access query parameters via url.searchParams, which is an instance of `URLSearchParams`:const foo = url.searCore conceptsRouting+page+page.jsageLoad} */ export function load({ params }) { if (params.slug === 'hello-world') { return { title: 'Hello world!', conteCore conceptsRouting+page+page.server.jsd} */ export async function load({ params }) { const post = await getPostFromDatabase(params.slug); if (post) { return post;AdvancedHooksServer hookslocalse also supports a second, optional parameter that gives you more control over how the response will be rendered. That parameter isBest practicesImages@sveltejs/enhanced-imgsrcset` and sizes`, you can do that with the w query parameter:<enhanced:img src="./image.png?w=1280;640;400" sizes="(min-width:1920px) 1280px,Core conceptsForm actionsProgressive enhancementCustomising use:enhancech accepts invalidateAll and reset parameters, or use applyAction on the result: <script> import { enhance, +++applyAction+++ }Core conceptsPage optionsprerenderWhen not to prerenderthat load data based on the page's parameters, such as a src/routes/blog/[slug]/+page.svelte route.Accessing `url.searchParams` duAppendixMigrating from SapperPages and layoutsStoreso properties. page now has url and params properties, but no path or query.You access them differently in SvelteKit. stores is nowDocsSvelte
- Template syntaxtransition:Transition parameters
Transitions can have parameters.(The double {{curlies}} aren't a special syntax; this is an object litTemplate syntaxanimate:Animation Parametersd transitions, animations can have parameters.(The double {{curlies}} aren't a special syntax; this is an object literal inside anTemplate syntax{#snippet ...}- copy: false ---> {#snippet name(param1, param2, paramN)}...{/snippet}Snippets, and render tags, are a way to create reusableReferenceCompiler errorspressionbind_group_invalid_snippet_parameter Cannot `bind:group` to a snippet parameterbind_invalid_expression Can only bind to anLegacy APIson:-> <script> let count = 0; /** @param {MouseEvent} event */ function handleClick(event) { count += 1; } </script>Runes$statePassing state into functionsvariables. In other words:/** * @param {number} a * @param {number} b */ function add(a, b) { return a + b; } let a = 1; letTemplate syntaxtransition:Custom transition functionstransition = (node: HTMLElement, params: any, options: { direction: 'in' | 'out' | 'both' }) => { delay?: number, duration?: nTemplate syntaxanimate:Custom animation functions, { from: DOMRect, to: DOMRect } , params: any) => { delay?: number, duration?: number, easing?: (t: number) => number, css?:Referencesvelte/reactivitySvelteURLSearchParamsversion of the built-in `URLSearchParams` object. Reading its contents (by iterating, or by calling params.get(...) or params.getTemplate syntax{@attach ...}Attachment factoriesent = $state('Hello!'); /** * @param {string} content * @returns {import('svelte/attachments').Attachment} */ function toTemplate syntaxuse:Typinge action applies to everything), a parameter, and any custom event handlers created by the action:<!--- file: App.svelte ---> <scrReferencesveltecreateRawSnippetatically function createRawSnippet<Params extends unknown[]>( fn: (...params: Getters<Params>) => { render: () => string;Referencesvelte/actionActionelements and optionally accepts a parameter which it has a default value for:export const myAction: Action<HTMLDivElement, { someReferencesvelte/transitionscalerom the provided values, passed as parameters, to an element's current (default) values. out transitions animate from an element'sReferencesvelteEventDispatcherds EventMap[Type] ? [type: Type, parameter?: EventMap[Type] | null | undefined, options?: DispatchOptions] : undefined extendsReferencesvelteSnippetn for more info. interface Snippet<Parameters extends unknown[] = []> {/*…*/} ( this: void, // this conditional allows tuplesReferencesvelte/transitionflyrom the provided values, passed as parameters to the element's default values. out transitions animate from the element's defaultTemplate syntax{#snippet ...}Typing snippets, since snippets can have multiple parameters.We can tighten things up further by declaring a generic, so that data and row referRuntimeContextType-safe contextm 'svelte'; const key = {}; /** @param {User} user */ export function setUserContext(user) { setContext(key, user); } export fMiscSvelte 4 migration guideStricter types for Svelte functions---const action: Action = (node, params) => { ... } // this is now an error if you use params in any way--- +++const action: ActReferencesvelte/legacyLegacyComponentTypes): SvelteComponent; ( ...args: Parameters<Component<Record<string, any>>> ): ReturnType< Component<Record<string, any>, RecTemplate syntax{@attach ...}Passing attachments to componentsent = $state('Hello!'); /** * @param {string} content * @returns {import('svelte/attachments').Attachment} */ function toReferencesvelte/actionActionReturnnction myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> { // ... return { update: (updatReferencesvelte/motionspringng would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user eLegacy APIsImperative component APIServer-side component APIder() method accepts the following parameters:undefined The options object takes in the following options:undefined const { headMiscTestingUnit and component tests with Viteste.value).toEqual(10); }); /** * @param {number} initial * @param {number} k */ export function multiplier(initial, k) { let cReferencesvelte/compilerASTlock'; expression: Identifier; parameters: Pattern[]; typeParams?: string; body: Fragment; } export interface AttributeReferencesvelte/transitioncrossfadefallback, ...defaults }: CrossfadeParams & { fallback?: ( node: Element, params: CrossfadeParams, intro: boolean ) => TraMiscTestingUnit and component tests with VitestUsing runes inside your test filese.value).toEqual(10); }); /** * @param {() => number} getCount * @param {number} k */ export function multiplier(getCount, k)TutorialAdvanced Svelte
- Reusing contentImplicit snippet props
ldren snippet. Since header has no parameters, we can turn it into children by removing the block tags... ---{#snippet header()}-Reusing contentSnippets and render tagset. Snippets can have zero or more parameters: <tbody> +++{#snippet monkey(emoji, description)}...{/snippet}+++ +++{@render moAdvanced transitionsAnimationshis case, so we can add a duration parameter: <li class={{ done: todo.done }} in:receive={{ key: todo.id }} out:send={{ key: t