Remote functions
Installation
Section titled “Installation”Pick the package that matches your project’s @sveltejs/kit major version.
sv add @sjsf does this for you.
npm i @sjsf/sveltekit3pnpm add @sjsf/sveltekit3yarn add @sjsf/sveltekit3bun add @sjsf/sveltekit3deno add @sjsf/sveltekit3Required peer dependencies: @sjsf/form@3.5.0 @sveltejs/kit@3.0.0 svelte@5.57.1
npm i @sjsf/sveltekitpnpm add @sjsf/sveltekityarn add @sjsf/sveltekitbun add @sjsf/sveltekitdeno add @sjsf/sveltekitRequired peer dependencies: @sjsf/form@3.5.0 @sveltejs/kit@2.61.0 esm-env@1.2.0 svelte@5.44.0
Example
Section titled “Example”<script lang="ts"> import { BasicForm, createForm } from "@sjsf/form"; import { connect } from "@sjsf/sveltekit3/rf/client";
import type { Model } from "#lib/post.js"; import * as defaults from "#lib/sjsf/remote-defaults.js";
import { createPost, getInitialData } from "./data.remote.js";
const initialData = await getInitialData();
// `connect()` takes care of the `/{formId}` suffix that Kit v3 requires on // every field name const form = createForm( await connect<Model>(createPost, { ...defaults, ...initialData, }) );</script>
<BasicForm {form} novalidate /><script lang="ts"> import { BasicForm, createForm } from "@sjsf/form"; import { connect } from "@sjsf/sveltekit3/rf/client";
import type { Model } from "#lib/post.js"; import * as defaults from "#lib/sjsf/remote-defaults.js";
import { createPost, getInitialData } from "./data.remote.js";
const initialData = await getInitialData();
createPost.enhance(async ({ submit }) => { if (await submit()) { console.log(createPost.result); form.reset(); } });
// `connect()` takes care of the `/{formId}` suffix that Kit v3 requires on // every field name const form = createForm( await connect<Model>(createPost, { ...defaults, ...initialData, }) );</script>
<BasicForm {form} novalidate />import type { InitialFormData } from "@sjsf/sveltekit3";import { createServerValidator } from "@sjsf/sveltekit3/rf/server";import { invalid } from "@sveltejs/kit";
import * as post from "#lib/post.js";import * as defaults from "#lib/sjsf/remote-defaults.js";import { form, query } from "$app/server";
export const getInitialData = query(async () => { return { ...post, initialValue: { title: "New post", content: "" }, } satisfies InitialFormData<post.Model>;});
export const createPost = form( createServerValidator<post.Model>({ ...defaults, ...post, }), ({ data }) => { if (data.title.length > 100) { invalid({ path: ["title"], message: "Title is too long" }); } console.log(data); return { ...data, id: "new-post" }; });import type { Schema, UiSchema } from "@sjsf/form";import type { FromSchema } from "json-schema-to-ts";
export const schema = { title: "Post", type: "object", properties: { title: { title: "Title", type: "string", }, content: { title: "Content", type: "string", minLength: 5, }, }, required: ["title", "content"],} as const satisfies Schema;
export type Model = FromSchema<typeof schema>;
export const uiSchema: UiSchema = { content: { "ui:components": { textWidget: "textareaWidget", }, },};Submission encoding
Section titled “Submission encoding”By default, enhanced submissions send the form’s own controls — the same parts a native submission would send — so the server parses both identically. No JSON serialization of the form value is involved.
Pass useJsonChunks to connect() to submit the form data as JSON. This needs JavaScript:
without it the browser submits the fields on its own, so the submission may look different from the JSON one.
Fields whose schema declares no type are rejected unless the validator is
given a convertUnknownEntry to handle them:
import type { FieldValue } from "@sjsf/form";
const validator = createServerValidator({ ...defaults, schema, convertUnknownEntry: ({ value }) => value as FieldValue,});Known issues
Section titled “Known issues”-
experimental.asyncdoes not apply to dependency code - issue.Add this to your
vite.config.jsoptimizeDeps: {exclude: ['@sjsf/form', '@sjsf/sveltekit3/rf/client'],} -
The
form.valuetype on the client side isunknownbecause theRemoteFormtype does not include information about the validator’s output type. Specify the type viaconnectgeneric:createForm(await connect<FormValue>(...)).