diff --git a/.changeset/chilled-fireants-learn.md b/.changeset/chilled-fireants-learn.md
new file mode 100644
index 000000000000..3796f57910ba
--- /dev/null
+++ b/.changeset/chilled-fireants-learn.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': major
+---
+
+breaking: remove deprecated `use:enhance` callback values
diff --git a/.changeset/mean-moose-smell.md b/.changeset/mean-moose-smell.md
new file mode 100644
index 000000000000..17d98b2cdbae
--- /dev/null
+++ b/.changeset/mean-moose-smell.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': major
+---
+
+breaking: error if form without multipart/form-data enctype contains a file input
diff --git a/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md b/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md
index 6cda9848e788..0f8babf08977 100644
--- a/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md
+++ b/documentation/docs/60-appendix/30-migrating-to-sveltekit-2.md
@@ -105,6 +105,16 @@ As such, SvelteKit 2 replaces `resolvePath` with a (slightly better named) funct
`svelte-migrate` will do the method replacement for you, though if you later prepend the result with `base`, you need to remove that yourself.
+## `form` and `data` have been removed from `use:enhance` callbacks
+
+If you provide a callback to [`use:enhance`](/docs/form-actions#progressive-enhancement-use-enhance), it will be called with an object containing various useful properties.
+
+In SvelteKit 1, those properties included `form` and `data`. These were deprecated some time ago in favour of `formElement` and `formData`, and have been removed altogether in SvelteKit 2.
+
+## Forms containing file inputs must use `multipart/form-data`
+
+If a form contains an `` but does not have an `enctype="multipart/form-data"` attribute, non-JS submissions will omit the file. SvelteKit 2 will throw an error if it encounters a form like this during a `use:enhance` submission to ensure that your forms work correctly when JavaScript is not present.
+
## Updated dependency requirements
SvelteKit requires Node `18.13` or higher, Vite `^5.0`, vite-plugin-svelte `^3.0`, TypeScript `^5.0` and Svelte version 4 or higher. `svelte-migrate` will do the `package.json` bumps for you.
diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts
index 0292c8cb285c..f60171d86015 100644
--- a/packages/kit/src/exports/public.d.ts
+++ b/packages/kit/src/exports/public.d.ts
@@ -1247,17 +1247,7 @@ export type SubmitFunction<
Failure extends Record | undefined = Record
> = (input: {
action: URL;
- /**
- * use `formData` instead of `data`
- * @deprecated
- */
- data: FormData;
formData: FormData;
- /**
- * use `formElement` instead of `form`
- * @deprecated
- */
- form: HTMLFormElement;
formElement: HTMLFormElement;
controller: AbortController;
submitter: HTMLElement | null;
@@ -1265,17 +1255,7 @@ export type SubmitFunction<
}) => MaybePromise<
| void
| ((opts: {
- /**
- * use `formData` instead of `data`
- * @deprecated
- */
- data: FormData;
formData: FormData;
- /**
- * use `formElement` instead of `form`
- * @deprecated
- */
- form: HTMLFormElement;
formElement: HTMLFormElement;
action: URL;
result: ActionResult;
diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js
index d1f6d70323e4..bd2a81fc8656 100644
--- a/packages/kit/src/runtime/app/forms.js
+++ b/packages/kit/src/runtime/app/forms.js
@@ -49,20 +49,6 @@ export function deserialize(result) {
return parsed;
}
-/**
- * @param {string} old_name
- * @param {string} new_name
- * @param {string} call_location
- * @returns void
- */
-function warn_on_access(old_name, new_name, call_location) {
- if (!DEV) return;
- // TODO 2.0: Remove this code
- console.warn(
- `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
- );
-}
-
/**
* Shallow clone an element, so that we can access e.g. `form.action` without worrying
* that someone has added an `` (https://github.com/sveltejs/kit/issues/7593)
@@ -157,11 +143,9 @@ export function enhance(form_element, submit = () => {}) {
if (DEV && clone(form_element).enctype !== 'multipart/form-data') {
for (const value of form_data.values()) {
if (value instanceof File) {
- // TODO 2.0: Upgrade to `throw Error`
- console.warn(
- 'Your form contains fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.'
+ throw new Error(
+ 'Your form contains fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.'
);
- break;
}
}
}
@@ -176,21 +160,12 @@ export function enhance(form_element, submit = () => {}) {
let cancelled = false;
const cancel = () => (cancelled = true);
- // TODO 2.0: Remove `data` and `form`
const callback =
(await submit({
action,
cancel,
controller,
- get data() {
- warn_on_access('data', 'formData', 'use:enhance submit function');
- return form_data;
- },
formData: form_data,
- get form() {
- warn_on_access('form', 'formElement', 'use:enhance submit function');
- return form_element;
- },
formElement: form_element,
submitter: event.submitter
})) ?? fallback_callback;
@@ -220,15 +195,7 @@ export function enhance(form_element, submit = () => {}) {
callback({
action,
- get data() {
- warn_on_access('data', 'formData', 'callback returned from use:enhance submit function');
- return form_data;
- },
formData: form_data,
- get form() {
- warn_on_access('form', 'formElement', 'callback returned from use:enhance submit function');
- return form_element;
- },
formElement: form_element,
update: (opts) =>
fallback_callback({
diff --git a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js b/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js
deleted file mode 100644
index 4bdf1c67412b..000000000000
--- a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.server.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// TODO 2.0: Remove this code and corresponding tests
-export const actions = {
- form_submit: () => {
- return {
- form_submit: true
- };
- },
-
- form_callback: () => {
- return {
- form_callback: true
- };
- },
-
- data_submit: () => {
- return {
- data_submit: true
- };
- },
-
- data_callback: () => {
- return {
- data_callback: true
- };
- }
-};
diff --git a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte b/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte
deleted file mode 100644
index 1768c5d9dc7b..000000000000
--- a/packages/kit/test/apps/basics/src/routes/actions/enhance/old-property-access/+page.svelte
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js
index cb6b4954e045..27b103347672 100644
--- a/packages/kit/test/apps/basics/test/test.js
+++ b/packages/kit/test/apps/basics/test/test.js
@@ -918,69 +918,21 @@ test.describe('Actions', () => {
expect(preSubmitContent).not.toBe(postSubmitContent);
});
- test('Submitting a form with a file input but no enctype="multipart/form-data" logs a warning', async ({
+ test('Submitting a form with a file input but no enctype="multipart/form-data" throws an error', async ({
page,
javaScriptEnabled
}) => {
test.skip(!javaScriptEnabled, 'Skip when JavaScript is disabled');
test.skip(!process.env.DEV, 'Skip when not in dev mode');
await page.goto('/actions/file-without-enctype');
- const log_promise = page.waitForEvent('console');
+ const error_promise = page.waitForEvent('pageerror');
await page.click('button');
- const log = await log_promise;
- expect(log.text()).toBe(
- 'Your form contains fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.'
+ const error = await error_promise;
+ expect(error.message).toBe(
+ 'Your form contains fields, but is missing the necessary `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819.'
);
});
- test('Accessing v2 deprecated properties results in a warning log', async ({
- page,
- javaScriptEnabled
- }) => {
- test.skip(!javaScriptEnabled, 'skip when js is disabled');
- test.skip(!process.env.DEV, 'skip when not in dev mode');
- await page.goto('/actions/enhance/old-property-access');
-
- for (const { id, old_name, new_name, call_location } of [
- {
- id: 'access-form-in-submit',
- old_name: 'form',
- new_name: 'formElement',
- call_location: 'use:enhance submit function'
- },
- {
- id: 'access-form-in-callback',
- old_name: 'form',
- new_name: 'formElement',
- call_location: 'callback returned from use:enhance submit function'
- },
- {
- id: 'access-data-in-submit',
- old_name: 'data',
- new_name: 'formData',
- call_location: 'use:enhance submit function'
- },
- {
- id: 'access-data-in-callback',
- old_name: 'data',
- new_name: 'formData',
- call_location: 'callback returned from use:enhance submit function'
- }
- ]) {
- await test.step(id, async () => {
- const log_promise = page.waitForEvent('console');
- const button = page.locator(`#${id}`);
- await button.click();
- await expect(button).toHaveAttribute('data-processed', 'true');
- const log = await log_promise;
- expect(log.text()).toBe(
- `\`${old_name}\` has been deprecated in favor of \`${new_name}\`. \`${old_name}\` will be removed in a future version. (Called from ${call_location})`
- );
- expect(log.type()).toBe('warning');
- });
- }
- });
-
test('Error props are returned', async ({ page, javaScriptEnabled }) => {
await page.goto('/actions/form-errors');
await page.click('button');
diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts
index 906332e3b809..3210343dd793 100644
--- a/packages/kit/types/index.d.ts
+++ b/packages/kit/types/index.d.ts
@@ -1229,17 +1229,7 @@ declare module '@sveltejs/kit' {
Failure extends Record | undefined = Record
> = (input: {
action: URL;
- /**
- * use `formData` instead of `data`
- * @deprecated
- */
- data: FormData;
formData: FormData;
- /**
- * use `formElement` instead of `form`
- * @deprecated
- */
- form: HTMLFormElement;
formElement: HTMLFormElement;
controller: AbortController;
submitter: HTMLElement | null;
@@ -1247,17 +1237,7 @@ declare module '@sveltejs/kit' {
}) => MaybePromise<
| void
| ((opts: {
- /**
- * use `formData` instead of `data`
- * @deprecated
- */
- data: FormData;
formData: FormData;
- /**
- * use `formElement` instead of `form`
- * @deprecated
- */
- form: HTMLFormElement;
formElement: HTMLFormElement;
action: URL;
result: ActionResult;