Status messages
A status message like “Form posted” can be displayed after submitting a form. The validation object contains a message
property used for this:
Usage
const { form, message } = superForm(data.form);
It is used to display the message on the client, like any other store:
{#if $message}
<div class="message">{$message}</div>
{/if}
However, we need to send it from the server first. Using the message
auxiliary function makes this rather simple.
The message helper
import { message, superValidate } from 'sveltekit-superforms/server';
export const actions = {
default: async ({ request }) => {
const form = await superValidate(request, schema);
if (!form.valid) {
// Will return fail(400, { form }) since form isn't valid
return message(form, 'Invalid form');
}
if (form.data.email.includes('spam')) {
// Will also return fail, since status is >= 400
// form.valid will also be set to false.
return message(form, 'No spam please', {
status: 403
});
}
// Just returns { form } with the message (and status code 200).
return message(form, 'Valid form!');
}
};
Strongly typed message
The message
is of type any
by default, but you can type it using superValidate
type parameters:
const form = await superValidate<typeof schema, string>(event, schema);
A string can be a bit limiting though; more realistically, there will be some kind of status for the form submission, so making a Message
type can be useful for consistency.
type Message = { status: 'error' | 'success' | 'warning'; text: string };
const form = await superValidate<typeof schema, Message>(event, schema);
To simplify this even further, if you have the same type for all status messages across the project, you can add a Message
type to the App.Superforms
namespace in src/app.d.ts, and it will be automatically set, no need for generic type parameters:
src/app.d.ts
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
namespace Superforms {
type Message = {
type: 'error' | 'success', text: string
}
}
}
}
src/routes/+page.svelte
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
const { form, message } = superForm(data.form);
</script>
{#if $message}
<div
class:success={$message.status == 'success'}
class:error={$message.status == 'error'}
>
{$message.text}
</div>
{/if}
Though if you want to keep it simple with a string or the default any
, you can use $page.status
to style the message appropriately:
<script lang="ts">
import { page } from '$app/stores';
import type { PageData } from './$types';
export let data: PageData;
const { form, message } = superForm(data.form);
</script>
{#if $message}
<div
class:success={$page.status == 200}
class:error={$page.status >= 400}
>
{$message}
</div>
{/if}
Using the message data programmatically
If you return data that you want to use programmatically instead of just displaying it, like in a toast message, you can do that in the onUpdate or onUpdated event:
const { form, enhance } = superForm(data.form, {
onUpdated({ form }) {
if (form.message) {
// Display the message using a toast library
toast(form.message.text, {
icon: form.message.status == 'success' ? '✅' : '❌'
});
}
}
});
The difference between the two events is that you can modify and cancel the update in onUpdate
, compared to onUpdated
, where the form data, errors, etc have already updated, making it best for non-store-related things like displaying a toast.
Limitations
Since there is no form data sent when redirecting, in that case the message will be lost. Since it’s common to redirect after a successful post, the message
property isn’t a general solution for displaying status messages.
The library sveltekit-flash-message is a complete solution that works with redirects, however. It can be directly integrated into Superforms, documented here.