Progressive enhancement
By using enhance
returned from superForm
, we’ll get the client-side enhancement expected from a modern website:
<script lang="ts">
const { form, enhance } = superForm(data.form);
// ^^^^^^^
</script>
<form method="POST" use:enhance>
Now all form submissions will happen on the client, and we unlock lots of client-side features like events, timers, auto error focus, etc.
The use:enhance
action takes no arguments; instead, events are used to hook into the default SvelteKit use:enhance parameters and more. Check out the events page for details.
Differences from SvelteKit’s use:enhance
There are three notable differences between the Superforms and SvelteKit enhance
.
1. ActionResult errors are changed to failure
Any ActionResult with status error
is transformed into failure
to avoid form data loss. The SvelteKit default is to render the nearest +error.svelte
page, which will wipe out the form and all data that was just entered. Returning fail
with a status message or using the onError event is a more user-friendly way of handling server errors.
2. The form isn’t resetted by default
Resetting the form is disabled as default to avoid accidental data loss. It’s not always wanted as well, for example in backend interfaces, where the form data should be kept after updating.
It’s easy to enable though, read further down at the resetForm
option for details.
3. A tainted form warning is added
Tainted fields is a feature which shows a dialog to the user when navigating away from a modified (“tainted” or “dirty”) form. This is enabled by default, again to avoid data loss for the user.
Usage
If you want to modify the basic use:enhance
behavior, here are the options available along with the default values; you don’t need to add them unless you want to change a value.
const { form, enhance, reset } = superForm(data.form, {
applyAction: true,
invalidateAll: true,
resetForm: false
});
When to change the defaults?
Quite rarely! If you have a single form on the page and nothing else is causing the page to invalidate, you’ll probably be fine as it is. For multiple forms on the same page, you have to experiment with these three options. Read more on the multiple forms page.
applyAction
and invalidateAll
are the most technical ones; if you’re dealing with a single form per page, you can most likely skip them.
applyAction
When applyAction
is true
, the form will have the default SvelteKit behavior of both updating and reacting on $page.form
and $page.status
, and also redirecting automatically.
Turning this behavior off can be useful when you want to isolate the form from other sources updating the page, for example Supabase events, a known source of confusing form behavior. Read more about applyAction
in the SvelteKit docs.
invalidateAll
When invalidateAll
is true
(the default) and a successful validation result is returned from the server, the page will be invalidated and the load functions will run again. A login form takes advantage of this to update user information on the page.
resetForm
When true
, reset the form upon a successful validation result.
Note however, that since we’re using bind:value
on the input fields, a HTML form reset (clearing all fields in the DOM) won’t have any effect. So in Superforms, resetting means going back to the initial state of the form data, basically setting $form
to what was initially sent to superForm
.
For a custom reset, you can instead modify the data
field returned from superValidate
on the server, or use the events together with the reset function on the client.
Making the form behave like the SvelteKit default
You can remove the differences described above by setting the following options. Use with care, since the purpose of the changes is to protect the user from data loss.
const { form, enhance } = superForm(data.form, {
// Reset the form upon a successful result
resetForm: true,
// On ActionResult error, render the nearest +error.svelte page
onError: 'apply',
// No message when navigating away from a modified form
taintedMessage: null
});