Skip to main content

$app/forms

import { function applyAction<Success extends Record<string, unknown> | undefined, Failure extends Record<string, unknown> | undefined>(result: ActionResult<Success, Failure>): Promise<void>

Updates the form property of the current page with the given data and updates page.status. In case of an error, it renders the nearest error page. In case of a redirect, it navigates to the redirect location.

applyAction
, function deserialize<Success extends Record<string, unknown> | undefined, Failure extends Record<string, unknown> | undefined>(result: string): ActionResult<Success, Failure>

Use this function to deserialize the response from a form submission. Usage:

import { deserialize } from '$app/forms';

async function handleSubmit(event) {
  const response = await fetch('/form?/action', {
	method: 'POST',
	body: new FormData(event.target)
  });

  const result = deserialize(await response.text());
  // ...
}
deserialize
,
function enhance<Success extends Record<string, unknown> | undefined, Failure extends Record<string, unknown> | undefined>(form_element: HTMLFormElement, submit?: SubmitFunction<Success, Failure>): {
    destroy(): void;
}

This action enhances a <form> element that otherwise would work without JavaScript.

The submit function is called upon submission with the given FormData and the action that should be triggered. If cancel is called, the form will not be submitted. You can use the abort controller to cancel the submission in case another one starts. If a function is returned, that function is called with the response from the server. If nothing is returned, the fallback will be used.

If this function or its return value isn't set, it emulates the browser-native behaviour, just without the full-page reload. It

  • resets the <form> element and refreshes all data in case of a successful submission with no redirect response
  • updates the form prop, page.form and page.status if the action is on the same page as the form
  • navigates to the page the submission lands on — populating that page's form prop and page.status — on success and failure if that isn't the current page, just as a native form submission would, but with the ?/actionName param stripped from the destination URL
  • redirects in case of a redirect response
  • renders the nearest error page in case of an unexpected error — the one nearest the action's route, if the action is on a different page

If you provide a custom function with a callback and want to use the default behavior, invoke update in your callback. It accepts an options object

  • reset: false if you don't want the <form> values to be reset after a successful submission
  • refreshAll to control whether all data is refreshed after submission; it defaults to true for successes and false for failures
  • navigate: false to apply non-redirect results to the current page rather than navigating to result.location; redirects are always followed
@param
form_element The form element
@param
submit Submit callback
enhance
} from '$app/forms';

applyAction

Updates the form property of the current page with the given data and updates page.status. In case of an error, it renders the nearest error page. In case of a redirect, it navigates to the redirect location.

function applyAction<
	Success extends Record<string, unknown> | undefined,
	Failure extends Record<string, unknown> | undefined
>(result: ActionResult<Success, Failure>): Promise<void>;

deserialize

Use this function to deserialize the response from a form submission. Usage:

import { function deserialize<Success extends Record<string, unknown> | undefined, Failure extends Record<string, unknown> | undefined>(result: string): ActionResult<Success, Failure>

Use this function to deserialize the response from a form submission. Usage:

import { deserialize } from '$app/forms';

async function handleSubmit(event) {
  const response = await fetch('/form?/action', {
	method: 'POST',
	body: new FormData(event.target)
  });

  const result = deserialize(await response.text());
  // ...
}
deserialize
} from '$app/forms';
async function function handleSubmit(event: any): Promise<void>handleSubmit(event: anyevent) { const const response: Responseresponse = await function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)fetch('/form?/action', { RequestInit.method?: string | undefined

A string to set request's method.

method
: 'POST',
RequestInit.body?: BodyInit | null | undefined

A BodyInit object or null to set request's body.

body
: new var FormData: new (form?: HTMLFormElement, submitter?: HTMLElement | null) => FormData

The FormData interface provides a way to construct a set of key/value pairs representing form fields and their values, which can be sent using the fetch(), XMLHttpRequest.send() or navigator.sendBeacon() methods. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

MDN Reference

FormData
(event: anyevent.target)
}); const const result: ActionResult<Record<string, unknown> | undefined, Record<string, unknown> | undefined>result = deserialize<Record<string, unknown> | undefined, Record<string, unknown> | undefined>(result: string): ActionResult<Record<string, unknown> | undefined, Record<string, unknown> | undefined>

Use this function to deserialize the response from a form submission. Usage:

import { deserialize } from '$app/forms';

async function handleSubmit(event) {
  const response = await fetch('/form?/action', {
	method: 'POST',
	body: new FormData(event.target)
  });

  const result = deserialize(await response.text());
  // ...
}
deserialize
(await const response: Responseresponse.Body.text(): Promise<string>text());
// ... }
function deserialize<
	Success extends Record<string, unknown> | undefined,
	Failure extends Record<string, unknown> | undefined
>(result: string): ActionResult<Success, Failure>;

enhance

This action enhances a <form> element that otherwise would work without JavaScript.

The submit function is called upon submission with the given FormData and the action that should be triggered. If cancel is called, the form will not be submitted. You can use the abort controller to cancel the submission in case another one starts. If a function is returned, that function is called with the response from the server. If nothing is returned, the fallback will be used.

If this function or its return value isn't set, it emulates the browser-native behaviour, just without the full-page reload. It

  • resets the <form> element and refreshes all data in case of a successful submission with no redirect response
  • updates the form prop, page.form and page.status if the action is on the same page as the form
  • navigates to the page the submission lands on — populating that page's form prop and page.status — on success and failure if that isn't the current page, just as a native form submission would, but with the ?/actionName param stripped from the destination URL
  • redirects in case of a redirect response
  • renders the nearest error page in case of an unexpected error — the one nearest the action's route, if the action is on a different page

If you provide a custom function with a callback and want to use the default behavior, invoke update in your callback. It accepts an options object

  • reset: false if you don't want the <form> values to be reset after a successful submission
  • refreshAll to control whether all data is refreshed after submission; it defaults to true for successes and false for failures
  • navigate: false to apply non-redirect results to the current page rather than navigating to result.location; redirects are always followed
function enhance<
	Success extends Record<string, unknown> | undefined,
	Failure extends Record<string, unknown> | undefined
>(
	form_element: HTMLFormElement,
	submit?: SubmitFunction<Success, Failure>
): {
	destroy(): void;
};

ActionResult

When calling a form action via fetch, the response will be one of these shapes.

<form method="post" use:enhance={() => {
	return ({ result }) => {
		// result is of type ActionResult
	};
}}

Success and failure results carry the root-relative pathname + search of the action URL, with the ?/actionName parameter removed. Redirect results carry the redirect target. Server-generated error results also carry the action location, while client-generated errors such as network failures do not. update uses this location to emulate native form navigation.

type ActionResult<
	Success extends Record<string, unknown> | undefined =
		Record<string, any>,
	Failure extends Record<string, unknown> | undefined =
		Record<string, any>
> =
	| {
			type: 'success';
			status: number;
			data?: Success;
			location: string;
	  }
	| {
			type: 'failure';
			status: number;
			data?: Failure;
			location: string;
	  }
	| { type: 'redirect'; status: number; location: string }
	| {
			type: 'error';
			status?: number;
			error: App.Error;
			location?: string;
	  };

SubmitFunction

type SubmitFunction<
	Success extends Record<string, unknown> | undefined =
		Record<string, any>,
	Failure extends Record<string, unknown> | undefined =
		Record<string, any>
> = (input: {
	action: URL;
	formData: FormData;
	formElement: HTMLFormElement;
	controller: AbortController;
	submitter: HTMLElement | null;
	cancel: () => void;
}) => MaybePromise<
	| void
	| ((opts: {
			formData: FormData;
			formElement: HTMLFormElement;
			action: URL;
			result: ActionResult<Success, Failure>;
			/**
			 * Call this to get the default behavior of a form submission response.
			 * @param options Set `reset: false` if you don't want the `<form>` values to be reset after a successful submission. `refreshAll` defaults to `true` for successful results and `false` for failures. When the submission navigates, setting it to `false` still runs the destination's `load` functions but may reuse shared layout data. Set `navigate: false` to apply non-redirect results to the current page instead of navigating to `result.location`. Redirects are always followed.
			 */
			update: (options?: {
				reset?: boolean;
				refreshAll?: boolean;
				navigate?: boolean;
				/** @deprecated Use `refreshAll` instead. */
				invalidateAll?: boolean;
			}) => Promise<void>;
	  }) => MaybePromise<void>)
>;

Edit this page on GitHub llms.txt