Skip to content
Playground

SvelteKit

Since this is a Svelte library, you may want to use it with the SvelteKit.

With this package you will be able to perform server-side validation of form data even if the user has JavaScript disabled.

Installation

Terminal window
npm i @sjsf/form @sjsf/sveltekit

Example

<script lang="ts">
import { FormContent } from "@sjsf/form";
import { createValidator } from "@sjsf/ajv8-validator";
import { theme } from "@sjsf/form/basic-theme";
import { translation } from "@sjsf/form/translations/en";
import { useSvelteKitForm, meta } from "@sjsf/sveltekit/client";
import type { PageData, ActionData } from "./$types";
const { form, enhance } = useSvelteKitForm(
meta<ActionData, PageData>(),
"form",
{
...theme,
validator: createValidator(),
translation,
}
);
</script>
<form
use:enhance
method="POST"
novalidate
style="display: flex; flex-direction: column; gap: 1rem"
>
<FormContent bind:value={form.formValue} />
<button type="submit" style="padding: 0.5rem;">Submit</button>
</form>

Server

On the server side you should implement at least one action which will always return the result of validateForm function (redirect and error helpers are allowed).

If the form data is passed as FormData, you need to create a parser for it.

import { makeFormDataParser, validateForm } from '@sjsf/sveltekit/server';
const validator = createValidator();
const parseFormData = makeFormDataParser({
validator
});
export const actions = {
default: async (event) => {
const form = validateForm({
schema,
validator,
data: await parseFormData({
schema,
request,
}),
})
if (!form.isValid) {
return fail(400, { form });
}
return {
form,
};
},
} satisfies Actions;

If you want to populate the form from the database, you can use the initForm function inside the load function.

import { initForm } from '@sjsf/sveltekit/server';
export const load = async () => {
const data = await getData();
const form = initForm({ schema, validator, initialValue: data });
return { form };
};

Client

On the client side you should call useSvelteKitForm.

import { useSvelteKitForm, meta } from '@sjsf/sveltekit/client';
import type { PageData, ActionData } from './$types';
const { form, mutation, enhance } = useSvelteKitForm(
meta<ActionData, PageData>(), "form", { /* form options */ }
);

According to Svelte documentation your form should always use POST requests.

<form use:enhance method="POST" novalidate style="display: flex; flex-direction: column; gap: 1rem">
<FormContent bind:value={form.formValue} />
<button type="submit" style="padding: 0.5rem;">Submit</button>
</form>

Progressive enhancement

You should always use enhance action on your forms.

But if you really want the form to work with JavaScript disabled, you should consider the following limitation:

  • validateForm should be called with sendData: true
  • Form elements for oneOf, anyOf, dependencies, additionalProperties and additionalItems will not update their state.
  • Some widgets (like multiselect, depends on the theme) may will not work, because they require JavaScript.
  • Conversion from FormData to JSON can happen with data loss. This conversion relies on the field names computation algorithm and it may lead to ambiguous results if the following conditions are violated:
    • Id prefix and separators:
      • Must be non empty, non numeric string
      • Must not include each other
    • Property names and keys of default object values in your schema must not contain the separators. If they do you can change the default separators with idSeparator and isPseudoSeparator options. Default separator values:
      • idSeparator - .
      • isPseudoSeparator - ::
    • If your schema contains additionalProperties:
      • Keys of initial object values must not contain the separators.
      • If you provide some initial value for additionalProperties or JavaScript is enabled but the form is used without enhance:
        • You should provide additionalPropertyKeyValidationError or additionalPropertyKeyValidator options to useSvelteKitForm for preventing the user to input invalid keys.
    • You may produce these checks at runtime with the staticAnalysis and other functions from @sjsf/form/static-analysis submodule. Functions from this submodule returns an iterable of errors, so you can:
      • Throw an error on the first error or list all errors (in a dev environment)
      • Check if the schema and id separator is correct and save the original form data if there are errors (in a production environment)