DocsSvelteKit
- Reference@sveltejs/kitAction
Shape of a form action method that is part of export const actions = {...} in +page.server.js. See forCore conceptsForm actionsAnatomy of an actionEach action receives a RequestEvent object, allowing you to read the data with request.formData(). AftCore conceptsForm actionsAnatomy of an actionValidation errors/** @satisfies {import('./$types').Actions} */ export const actions = { login: async ({ cookies, request }) => { const data = aCore conceptsForm actionsAnatomy of an actionRedirects/** @satisfies {import('./$types').Actions} */ export const actions = { login: async ({ cookies, request, +++url+++ }) => { conCore conceptsForm actionsA +page.server.js file can export actions, which allow you to POST data to the server using the <form>Reference@sveltejs/kitActionFailureinterface ActionFailure< T extends Record<string, unknown> | undefined = undefined > {/*…*/} status:Reference@sveltejs/kitActionResultWhen calling a form action via fetch, the response will be one of these shapes.<form method="post" useReference@sveltejs/kitActionsShape of the export const actions = {...} object in +page.server.js. See form actions for more informaCore conceptsForm actionsDefault actionsst case, a page declares a default action: /** @satisfies {import('./$types').Actions} */ export const actions = { default: asynCore conceptsForm actionsNamed actionsInstead of one default action, a page can have as many named actions as it needs: /** @satisfies {impCore conceptsForm actionsLoading dataAfter an action runs, the page will be re-rendered (unless a redirect or an unexpected error occurs),Core conceptsForm actionsAlternativesForm actions are the preferred way to send data to the server, since they can be progressively enhanceCore conceptsForm actionsGET vs POSTAs we've seen, to invoke a form action you must use method="POST".Some forms don't need to PCore conceptsForm actionsProgressive enhancementeceding sections we built a /login action that works without client-side JavaScript — not a fetch in sight. That's great, but whenCore conceptsForm actionsProgressive enhancementuse:enhancee a form is to add the use:enhance action: <script> +++import { enhance } from '$app/forms';+++ /** @type {import('./$types').Core conceptsForm actionsProgressive enhancementCustomising use:enhanceurns a callback that runs with the ActionResult.<form method="POST" use:enhance={({ formElement, formData, action, cancel, submiCore conceptsForm actionsProgressive enhancementCustom event listener'$app/navigation'; import { applyAction, deserialize } from '$app/forms'; /** @type {import('./$types').PageProps} */ let { fBest practicesAuthhorization means determining which actions they are allowed to take.Reference@sveltejs/kitfailCreate an ActionFailure object. Call when form submission fails. function fail(status: number): ActionReference@sveltejs/kitCspnamespace Csp { type ActionSource = 'strict-dynamic' | 'report-sample'; type BaseSource = | 'self'Reference@sveltejs/kitCspDirectivesault-src'?: Array<Csp.Source | Csp.ActionSource>; 'frame-src'?: Csp.Sources; 'worker-src'?: Csp.Sources; 'connect-src'?: CspReference$app/formsapplyActionThis action updates the form property of the current page with the given data and updates page.status.Reference$app/formsenhanceThis action enhances a <form> element that otherwise would work without JavaScript.The submit functionReference@sveltejs/kitSubmitFunctionRecord<string, any> > = (input: { action: URL; formData: FormData; formElement: HTMLFormElement; controller: AbortConAdvancedPackagingBest practiceske the current URL or a navigation action as a prop rather than relying directly on $app/state, $app/navigation, etc. Writing yourReference@sveltejs/kitisActionFailureChecks whether this is an action failure thrown by fail. function isActionFailure(e: unknown): e is AcReference$app/servergetRequestEventrver hooks, server load functions, actions, and endpoints (and functions called by them).In environments without `AsyncLocalStoragCore conceptsState managementAvoid shared state on the server/** @satisfies {import('./$types').Actions} */ export const actions = { default: async ({ request }) => { const data = await reAppendixMigrating to SvelteKit v2Improved error handlingfor POST requests to pages without actions) don't trigger handleError at all, but should. In the latter case, the resulting $page.Reference$app/formsdeserializenst response = await fetch('/form?/action', { method: 'POST', body: new FormData(event.target) }); const result = deserialiReference$app/navigationdisableScrollHandling(in onMount or afterNavigate or an action, for example), this disables SvelteKit's built-in scroll handling. This is generally disCore conceptsRouting$typesPageData, form: import('./$types').ActionData }} */ let { data, form } = $props(); ``` Or, for a layout: ```js /// file: +layoutAppendixGlossaryPrerenderingver, and the page must not contain actions. Note that you can still prerender content that is loaded based on the page's parameterReference@sveltejs/kitHandleFetchndering) inside an endpoint, load, action, handle, handleError or reroute. type HandleFetch = (input: { event: RequestEvent; reqReferenceTypesGenerated typesunion of the return values of all Actions is available as ActionData.Starting with version 2.16.0, two additional helper types arCore conceptsLoading dataUsing `getRequestEvent`ogin in any load function (or form action, for example) to guarantee that the user is logged in:import { requireLogin } from '$libCore conceptsState managementStoring state in the URL<a href="..."> or <form action="..."> attributes, or set them programmatically via goto('?key=value'Build and deployStatic site generationGitHub Pagesdefault config;You can use GitHub actions to automatically deploy your site to GitHub Pages when you make a change. Here's an exaReference@sveltejs/kitPageafter a form submission. See form actions for more info.AdvancedHooksServer hookshandleFetchndering) inside an endpoint, load, action, handle, handleError or reroute.For example, your load function might make a request toBuild and deployStatic site generationGitHub Pagesfile: .github/workflows/deploy.yml- name: Checkout uses: actions/checkout@v4 # If you're using pnpm, add this step then change the commands and cache kAdvancedHooksUniversal hookstransportypes — returned from load and form actions — across the server/client boundary. Each transporter contains an encode function, whicCore conceptsRouting+serverReceiving dataa + b); }[!NOTE] In general, [form actions](form-actions) are a better way to submit data from the browser to the server. [!NOTE]Core conceptsRouting+page+page.server.jsage.server.js file can also export actions. If load lets you read data from the server, actions let you write data to the server uCore conceptsPage optionsprerenderWhen not to prerenderfor example in onMount).Pages with actions cannot be prerendered, because a server must be able to handle the action POST requestsBuild and deployNode serversEnvironment variablesORIGIN`, PROTOCOL_HEADER`, `HOST_HEADER`, and `PORT_HEADER`erience this error when using form actions:[!NOTE] Cross-site POST form submissions are forbiddenDocsSvelte
- Referencesvelte/actionAction
Actions are functions that are called when an element is created. You can use this interface to type sReferencesvelte/action Referencesvelte/actionActionReturnActions can return an object containing the two properties defined in this interface. Both are optionaTemplate syntax{@attach ...}Converting actions to attachmentsusing a library that only provides actions, you can convert them to attachments with `fromAction`, allowing you to (for example) uTemplate syntaxuse:are more flexible and composable. Actions are functions that are called when an element is mounted. They are added with the use:ReferenceCompiler warningsvents, a11y_no_static_element_interactions (because of reasons) --> <div onclick>...</div> a11y_accesskey Avoid using accesskeyEnfSpecial elements<svelte:document>re on window. It also lets you use actions on document.As with <svelte:window>, this element may only appear the top level of yourSpecial elements<svelte:body>re on window. It also lets you use actions on the <body> element.As with <svelte:window> and <svelte:document>, this element may oTemplate syntax{@attach ...}Controlling when attachments re-runAttachments, unlike actions, are fully reactive: {@attach foo(bar)} will re-run on changes to foo or bTemplate syntaxuse:TypingThe Action interface receives three optional type arguments — a node type (which can be Element, if thTemplate syntaxanimate:Animation ParametersAs with actions and transitions, animations can have parameters.(The double {{curlies}} aren't a speciMiscTypeScriptEnhancing built-in DOM typeses or custom events coming from an action. In these cases, TypeScript will throw a type error, saying that it does not know theseMiscSvelte 4 migration guideStricter types for Svelte functionsr types for createEventDispatcher, Action, ActionReturn, and onMount:undefined import { createEventDispatcher } from 'svelte';Referencesvelte/attachmentsfromActionConverts an action into an attachment keeping the same behavior. It's useful if you want to start usinReferencesvelte/legacynonpassiveevent modifier, implemented as an action function nonpassive( node: HTMLElement, [event, handler]: [ event: string, handlerReferencesvelte/legacypassiveevent modifier, implemented as an action function passive( node: HTMLElement, [event, handler]: [ event: string, handler: (RuntimeImperative component APImount(including onMount callbacks, and action functions) will not run during mount. If you need to force pending effects to run (in thTemplate syntaxBasic markupEventson` instead (for example inside an action).MiscSvelte 5 migration guideEvent changesEvent modifiers't! — then you will need to use an action to apply the event handler yourself.MiscSvelte 5 migration guideBreaking changes in runes modeTouch and wheel events are passiveon` instead (for example inside an action).ExamplesActions
TutorialBasic SvelteKit
- FormsNamed form actions
A page that only has a single action is, in practice, quite rare. Most of the time you'll need to haveHeaders and cookiesSetting headersload function (as well as in form actions, hooks and API routes, which we'll learn about later) you have access to a setHeaders fAPI routesPOST handlersIn most cases, you should use form actions instead — you'll end up writing less code, and it'll work without JavaScript, making itFormsValidationas required: <form method="POST" action="?/create"> <label> add a todo <input name="description" autocomplete="offFormsCustomizing use:enhanceing an artificial delay to our two actions: export const actions = { create: async ({ cookies, request }) => { +++await new PrFormsThe <form> elemente we haven't created a server-side action to handle the POST request. Let's do that now: import * as db from '$lib/server/databasFormsProgressive enhancementrm> elements: <form method="POST" action="?/create" +++use:enhance+++> <form method="POST" action="?/delete" +++use:enhancErrors and redirectsFallback errorsyout.server.js file to see this in action: export function load() { throw new Error('yikes'); }You can customise the fallback erErrors and redirectsRedirectst(...) inside load functions, form actions, API routes and the handle hook, which we'll discuss in a later chapter.The most commonTutorialAdvanced SvelteKit
- HooksThe RequestEvent object
I routes in +server.js files, form actions in +page.server.js files, and load functions in +page.server.js and +layout.server.js.IHookshandleError/the-bad-place, you'll see this in action — the error page is shown, and if you open the terminal (using the button to the right oPage optionsprerenderand the page must not contain form actions. Pages with dynamic route parameters can be prerendered as long as they are specified iAdvanced routingRoute groupsthe /login route, which has a form action in src/routes/login/+page.server.js that sets the logged_in cookie.We can also add someEnvironment variables$env/static/privateprivate and use it inside the form action: import { redirect, fail } from '@sveltejs/kit'; +++import { PASSPHRASE } from '$env/stEnvironment variables$env/dynamic/private7, '/welcome'); } } export const actions = { default: async ({ request, cookies }) => { const data = await request.formData()