### Install and Run Superforms with npm Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-contributing-+page.md Use these commands to install dependencies and start the development server for Superforms using npm. ```bash npm install npm run dev ``` -------------------------------- ### Install and Run Superforms with pnpm Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-contributing-+page.md Use these commands to install dependencies and start the development server for Superforms using pnpm. ```bash pnpm install pnpm dev ``` -------------------------------- ### Login Endpoint Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md An example demonstrating how to use `actionResult` and `superValidate` within a SvelteKit server route (`+server.ts`) to handle a login POST request. ```APIDOC ## Login Request Example ### File: `src/routes/login/+server.ts` ### Description This example shows a `POST` handler for a login endpoint. It uses `superValidate` to validate incoming form data against a schema, and `actionResult` to return appropriate responses based on validation success or failure. ### Code ```ts import { actionResult, superValidate, setMessage } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; const loginSchema = z.object({ email: z.string().email(), password: z.string().min(5) }); export const POST = async ({ request }) => { const form = await superValidate(request, zod(loginSchema)); if (!form.valid) return actionResult('failure', { form }); // TODO: Verify login here // setMessage(form, 'Login successful!'); return actionResult('success', { form }); }; ``` ### Frontend Usage To use this endpoint with a form that has `use:enhance` applied: ```svelte
``` ``` -------------------------------- ### Import Superform and Defaults Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Import the necessary functions from the sveltekit-superforms library to get started. ```typescript import { superForm, defaults } from 'sveltekit-superforms'; ``` -------------------------------- ### Login Endpoint Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md An example of a SvelteKit login endpoint using Superforms for validation and constructing an API route result. It validates the login credentials and returns a success or failure result. ```typescript import { actionResult, superValidate, setMessage } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; const loginSchema = z.object({ email: z.string().email(), password: z.string().min(5) }); export const POST = async ({ request }) => { const form = await superValidate(request, zod(loginSchema)); if (!form.valid) return actionResult('failure', { form }); // TODO: Verify login here // setMessage(form, 'Login successful!'); return actionResult('success', { form }); }; ``` -------------------------------- ### Create New SvelteKit Project with pnpm Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use 'pnpx sv create my-app' to start a new SvelteKit project when using pnpm. ```bash pnpx sv create my-app ``` -------------------------------- ### Create New SvelteKit Project with npm Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use 'npx sv create my-app' to start a new SvelteKit project when using npm. ```bash npx sv create my-app ``` -------------------------------- ### onResult: Redirect Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-events-+page.md Example of using onResult to handle redirects when applyAction is set to false. ```typescript const { form, enhance } = superForm(data.form, { applyAction: false, onResult({ result }) { if (result.type === 'redirect') { goto(result.location); } } }); ``` -------------------------------- ### Form Action with Message Examples Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Demonstrates using the message function within a SvelteKit form action to handle validation and user feedback. Includes examples for invalid forms, specific error messages with custom statuses, and success messages. ```typescript import { message, superValidate } from 'sveltekit-superforms/server'; export const actions = { default: async (event) => { const form = await superValidate(event, 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 return fail and set form.valid = false, since status is >= 400 return message(form, 'No spam please', { status: 403 }); } // Returns { form } return message(form, 'Valid form!'); } }; ``` -------------------------------- ### Multiple Files Upload with File Proxy Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Example for handling multiple file uploads using `bind:files`. The input field should have the `multiple` attribute. ```svelte
{#if $errors.images}{$errors.images}{/if}
``` -------------------------------- ### Handling Promises with SuperDebug Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md Load and display data from a promise using SuperDebug. This example fetches product data. ```ts // +page.ts export const load = (async ({ fetch }) => { const promiseProduct = fetch('https://dummyjson.com/products/1') .then(response => response.json()) return { promiseProduct } }) ``` ```svelte ``` -------------------------------- ### SuperValidate with Zod Adapter Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Demonstrates using the zod adapter with superValidate. It shows how to import necessary types and functions from 'sveltekit-superforms/adapters' and 'zod', and then creates an adapter instance for a Zod schema. ```typescript import type { Infer, InferIn } from 'sveltekit-superforms'; import { zod, zodClient } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; const schema = z.object({ name: z.string().min(3) }) // Type is now ValidationAdapter, InferIn> // Which is the same as ValidationAdapter<{name: string}, {name: string}> const adapter = zod(schema); ``` -------------------------------- ### Using the Generic TextField Component Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-components-+page.md Example of how to use the generic TextField component with a Superform instance and a specific field name. ```svelte ``` -------------------------------- ### Multiple Files Upload with on:input Handler Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Example for multiple file uploads using an `on:input` handler. It converts the FileList to an array. Note that the input cannot be hidden with an `{#if}` block when not using `bind:files`. ```svelte
($form.images = Array.from(e.currentTarget.files ?? []))} /> {#if $errors.images}{$errors.images}{/if}
``` -------------------------------- ### Basic Server-Side Rate Limiting with sveltekit-rate-limiter Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-rate-limiting-+page.md Implement IP and IP+User Agent rate limiting for form actions. Ensure the 'sveltekit-rate-limiter' library is installed. Each call to 'isLimited' counts as a hit. ```typescript import { error } from '@sveltejs/kit'; import { RateLimiter } from 'sveltekit-rate-limiter/server'; const limiter = new RateLimiter({ IP: [10, 'h'], // IP address limiter IPUA: [5, 'm'], // IP + User Agent limiter }); export const actions = { default: async (event) => { // Every call to isLimited counts as a hit towards the rate limit for the event. if (await limiter.isLimited(event)) error(429); } }; ``` -------------------------------- ### Initialize Superform and Message Store Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-messages-+page.md Import and initialize `superForm` to get access to the form data and the `message` store for displaying status messages. ```typescript const { form, message } = superForm(data.form); ``` -------------------------------- ### Handling Special Input Formats (Date) Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-client-validation-+page.md For specific input types like 'date', ensure the data and constraints match the required `yyyy-mm-dd` format. This example shows how to use a proxy object and spread constraints, with manual attribute setting for `min` to format the date correctly. ```svelte ``` -------------------------------- ### Single File Upload with on:input Handler Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Example of a single file input using an `on:input` handler to manually set the form data. Note the type casting to `File` and potential `null` value. ```svelte
($form.image = e.currentTarget.files?.item(0) as File)} /> {#if $errors.image}{$errors.image}{/if}
``` -------------------------------- ### Displaying Files with SuperDebug Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md SuperDebug can display File and FileList objects. This example shows its capability with form data containing files. ```svelte ``` -------------------------------- ### Single File Upload with File Proxy Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Example of a single file input using the `bind:files` directive for form data binding. Ensure the form has `enctype="multipart/form-data"`. ```svelte
{#if $errors.image}{$errors.image}{/if}
``` -------------------------------- ### Displaying Rejected Promises with SuperDebug Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md Debug a rejected promise using SuperDebug. This example simulates a broken promise. ```ts // +page.ts export const load = (async ({ fetch }) => { const rejected = Promise.reject(throw new Error('Broken promise')) return { rejected } }) ``` ```svelte ``` -------------------------------- ### Zod Refine for Password Confirmation Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-nested-data-+page.md Example of using Zod's `refine` to ensure two password fields match. The `path` option specifies where the error should be attached. ```typescript const confirmPassword = z .object({ password: z.string(), confirm: z.string(), }) .refine((data) => data.password === data.confirm, { message: "Passwords don't match", path: ["confirm"], // path of error }); ``` -------------------------------- ### SvelteKit Page with Superform Enhancement Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-migration-v2-+page.md Example of a SvelteKit page using the `enhance` action with a custom `TextInput` component for form submission. ```svelte
``` -------------------------------- ### Using defaults with Initial Data Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-migration-v2-+page.md Use `defaults` with initial data when providing starting values for a form. The initial data can be partial and will not be validated by this function. ```typescript import { defaults } from 'sveltekit-superforms' // Supplying initial data (can be partial, won't be validated) const initialData = { name: 'New user' } const { form, errors, enhance } = superForm(defaults(initialData, zod(schema)), { SPA: true, validators: zod(schema), // ... }) ``` -------------------------------- ### Custom Styling with SuperDebug Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md Customize the appearance of SuperDebug using the 'theme' prop and CSS variables. This example uses the 'vscode' theme and customizes the date color. ```svelte ``` -------------------------------- ### Delayed Submit Button Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-crud-+page.md An example of a button that can be used to trigger a delayed form submission, useful for simulating network latency. ```svelte ``` -------------------------------- ### Zod Catch-all Schema for Extra Fields Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-strict-mode-+page.md Configure a Zod schema with `.catchall()` to validate unknown fields. This example demonstrates how to handle extra fields, expecting them to be integers. ```typescript import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; const schema = z.object({ name: z.string().min(1) }) .catchall(z.number().int()); // All unknown fields should be integers export const actions = { default: async ({ request }) => { const form = await superValidate(request, zod(schema)); if (!form.valid) { return fail(400, { form }); } // Typed as string, as expected console.log(form.data.name); // All other keys are typed as number console.log(form.data.first, form.data.second); return { form }; } }; ``` -------------------------------- ### Sending Status Messages from Server Actions Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-messages-+page.md Use the `message` helper function within SvelteKit server actions to send status messages back to the client. This example demonstrates sending a validation error, a forbidden request, and a successful form submission message. ```typescript import { message, superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; export const actions = { default: async ({ request }) => { const form = await superValidate(request, zod(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!'); } }; ``` -------------------------------- ### onUpdate: Modifying Form Data and Handling Extra Data Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-events-+page.md Example of using onUpdate to process form data and handle extra data returned from the server action. Requires importing FormResult and ActionData types. ```typescript import { superForm, type FormResult } from 'sveltekit-superforms'; import type { ActionData, PageData } from './$types.js'; let { data } : { data: PageData } = $props(); const { form, errors, message, enhance } = superForm(data.form, { onUpdate({ form, result }) { const action = result.data as FormResult; // If you've returned from the form action: // return { form, extra: 123 } if (form.valid && action.extra) { // Do something with the extra data } } }); ``` -------------------------------- ### Numeric Enum Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-migration-v2-+page.md In v2, numeric enums cannot be posted as strings. This example shows the enum definition. ```typescript enum FetchStatus { Idle = 0, Submitting = 1, Delayed = 2, Timeout = 3 } ``` -------------------------------- ### Create New SvelteKit Project Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-crud-+page.md Use this command to create a new SvelteKit project for the CRUD tutorial. Select 'Skeleton project' and 'Typescript syntax' when prompted. ```bash npx sv create sf-crud ``` ```bash pnpx sv create sf-crud ``` -------------------------------- ### Type T Definition Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Defines the type T, representing the validation schema, which extends Record. This example shows an optional string for 'name' and a required string for 'email'. ```typescript type T = { name?: string | undefined, email: string }; ``` -------------------------------- ### Type M Definition Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Defines the type M, which represents the status message type. It defaults to 'any'. ```typescript type M = any; ``` -------------------------------- ### Importing Proxy Primitives and File Proxies Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Imports necessary proxy functions for various data types and file handling from 'sveltekit-superforms'. ```typescript import { // The primitives return a Writable: booleanProxy, dateProxy, intProxy, numberProxy, stringProxy, // File proxies fileProxy, fileFieldProxy, // formFieldProxy // File[] proxies filesProxy, filesFieldProxy, // arrayProxy // The type of the others depends on the field: formFieldProxy, arrayProxy, fieldProxy } from 'sveltekit-superforms'; ``` -------------------------------- ### Add CSS to app.html Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-crud-+page.md Include these links in the `` of your `src/app.html` file for improved styling with normalize.css and sakura.css. ```html ``` -------------------------------- ### Initialize Form with Joi Schema Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `joi` adapter for Joi schemas. Define the schema outside the load function for caching. ```typescript import { superValidate } from 'sveltekit-superforms'; import { joi } from 'sveltekit-superforms/adapters'; import Joi from 'joi'; // Define outside the load function so the adapter can be cached const schema = Joi.object({ name: Joi.string().default('Hello world!'), email: Joi.string().email().required() }); export const load = async () => { const form = await superValidate(joi(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Using intProxy with Superform Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-proxy-objects-+page.md Demonstrates how to use `intProxy` to bind to a number field. It shows how to use the form store or the entire superForm object as input, and how to control form tainting. ```typescript import { superForm, intProxy } from 'sveltekit-superforms'; // Assume the following schema: // { id: number } const superform = superForm(data.form); const { form, errors, enhance } = superform; // Returns a Writable const idProxy = intProxy(form, 'id'); // Use the whole superForm object to prevent tainting const idProxy2 = intProxy(superform, 'id', { taint: false }); ``` -------------------------------- ### Login and Registration Form Handling (+page.server.ts) Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-multiple-forms-+page.md This server-side code defines separate schemas for login and registration, initializes both forms, and handles their respective actions. Different schema types mean no 'id' is required. ```typescript import { z } from 'zod'; import { fail } from '@sveltejs/kit'; import { message, superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import type { Actions, PageServerLoad } from './$types'; const loginSchema = z.object({ email: z.string().email(), password: z.string().min(8) }); const registerSchema = z.object({ email: z.string().email(), password: z.string().min(8), confirmPassword: z.string().min(8) }); export const load: PageServerLoad = async () => { // Different schemas, no id required. const loginForm = await superValidate(zod(loginSchema)); const registerForm = await superValidate(zod(registerSchema)); // Return them both return { loginForm, registerForm }; }; export const actions = { login: async ({ request }) => { const loginForm = await superValidate(request, zod(loginSchema)); if (!loginForm.valid) return fail(400, { loginForm }); // TODO: Login user return message(loginForm, 'Login form submitted'); }, register: async ({ request }) => { const registerForm = await superValidate(request, zod(registerSchema)); if (!registerForm.valid) return fail(400, { registerForm }); // TODO: Register user return message(registerForm, 'Register form submitted'); } } satisfies Actions; ``` -------------------------------- ### Hidden Form Action for Validation Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-multiple-forms-+page.md Define a form action for the hidden form to handle validation and server-side logic. This example uses Zod for schema validation. ```typescript const usernameSchema = fullSchema.pick({ username: true }); export const actions: Actions = { check: async ({ request }) => { const form = await superValidate(request, zod(usernameSchema)); if (!form.valid) return fail(400, { form }); if(!checkUsername(form.data.username)) { setError(form, 'username', 'Username is already taken.'); } return { form }; } }; ``` -------------------------------- ### Initialize Form with ArkType Adapter Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Initialize a Superform in a SvelteKit load function using the ArkType adapter. Ensure the schema is defined outside the load function for caching. ```typescript import { superValidate } from 'sveltekit-superforms'; import { arktype } from 'sveltekit-superforms/adapters'; import { type } from 'arktype'; // Define outside the load function so the adapter can be cached const schema = type({ name: 'string = "Hello world!"', email: 'email' }); export const load = async () => { const form = await superValidate(arktype(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Initialize Form with Valibot Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `valibot` adapter for Valibot schemas. Define the schema outside the load function. ```typescript import { superValidate } from 'sveltekit-superforms'; import { valibot } from 'sveltekit-superforms/adapters'; import { object, string, email, optional, pipe, minLength } from 'valibot'; // Define outside the load function so the adapter can be cached const schema = object({ name: pipe(optional(string(), 'Hello world!'), minLength(2)), email: pipe(string(), email()) }); export const load = async () => { const form = await superValidate(valibot(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Zod Schema for Nested Data Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-nested-data-+page.md Define a Zod schema for nested objects within an array. This example shows a schema for an array of tag objects, each with an `id` and `name`. ```typescript const schema = z.object({ tags: z.object({ id: z.number().int().min(1), name: z.string().min(2) }) .array() }); const tags = [{ id: 1, name: 'test' }]; export const load = async () => { const form = await superValidate({ tags }, zod(schema)); return { form }; }; ``` -------------------------------- ### Programmatically handle messages with `message()` Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-messages-+page.md Use the `message()` function to return structured message data from a form action. This data can then be used programmatically, for example, in toast notifications. ```typescript return message(form, { status: 'success', text: 'All went well' }); ``` -------------------------------- ### Superform onUpdated Event Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-events-+page.md Use onUpdated to perform actions after form validation, such as displaying a toast notification on success. The form parameter provides read-only validation results. ```typescript onUpdated: ({ form }) => void ``` ```typescript const { form, enhance } = superForm(data.form, { onUpdated({ form }) { if (form.valid) { // Successful post! Do some more client-side stuff, // like showing a toast notification. toast(form.message, { icon: '✅' }); } } }); ``` -------------------------------- ### Importing Proxy Primitives Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-proxy-objects-+page.md Import the necessary proxy functions from 'sveltekit-superforms'. These include primitives for common types and more general field/array proxies. ```typescript import { // The primitives return a Writable: booleanProxy, dateProxy, intProxy, numberProxy, stringProxy, // The type of the other three depends on the field: formFieldProxy, arrayProxy, fieldProxy } from 'sveltekit-superforms'; ``` -------------------------------- ### Initialize Form with JSON Schema Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `schemasafe` adapter for JSON Schemas. The adapter must be defined before `superValidate`. ```typescript import { superValidate, type JSONSchema } from 'sveltekit-superforms'; import { schemasafe } from 'sveltekit-superforms/adapters'; export const schema = { type: 'object', properties: { name: { type: 'string', minLength: 2, default: 'Hello world!' }, email: { type: 'string', format: 'email' } }, required: ['name', 'email'], additionalProperties: false, $schema: 'http://json-schema.org/draft-07/schema#' } as const satisfies JSONSchema; export const load = async () => { // The adapter must be defined before superValidate for JSON Schema. const adapter = schemasafe(schema); const form = await superValidate(request, adapter); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Union with Default Value Schema Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-whats-new-v2-+page.md When using union types in schemas, an explicit default value must be provided. This example shows a union of string and number with a default of 0. ```typescript const schema = z.object({ undecided: z.union([z.string(), z.number()]).default(0) }) ``` -------------------------------- ### Get Default Form Values Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Retrieves the default values for a given schema, whether they are Superforms defaults or custom ones defined in the schema. This is useful for initializing form data. ```typescript import { defaultValues } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; const schema = z.object({ name: z.string().min(2), tags: z.string().min(1).array().default(['a', 'b']) }); // Returns { name: '', tags: ['a', 'b'] } const defaults = defaultValues(zod(schema)); ``` -------------------------------- ### Using SuperDebug with Stores Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md Pass a Svelte store directly to the 'data' prop of SuperDebug for live updates. ```svelte ``` -------------------------------- ### Returning Files with SvelteKit's Fail and withFiles Helper Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Shows how to use SvelteKit's `fail` function in conjunction with Superforms' `withFiles` helper when dealing with file uploads. The `withFiles` helper ensures files are properly handled for serialization. ```typescript // Importing the default fail: import { fail } from '@sveltejs/kit'; // Prefer to import message, setError and fail from here instead: import { withFiles } from 'sveltekit-superforms'; // With the @sveltejs/kit fail: if (!form.valid) { return fail(400, withFiles({ form })); } // When returning just the form return withFiles({ form }) ``` -------------------------------- ### Nested Type Definition Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Illustrates the Nested type, which replaces primitive values in T with R and removes optional modifiers. Here, it transforms the T type to have string arrays for both 'name' and 'email'. ```typescript type Nested = { name: string[], email: string[] }; ``` -------------------------------- ### Initialize Form with Superstruct Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `superstruct` adapter for Superstruct schemas. Define the schema and defaults outside the load function. ```typescript import { superValidate } from 'sveltekit-superforms'; import { superstruct } from 'sveltekit-superforms/adapters'; import { object, string, defaulted, define } from 'superstruct'; const email = () => define('email', (value) => String(value).includes('@')); // Define outside the load function so the adapter can be cached const schema = object({ name: defaulted(string(), 'Hello world!'), email: email() }); // Defaults should also be defined outside the load function const defaults = { name: 'Hello world!', email: '' }; export const load = async () => { const form = await superValidate(superstruct(schema, { defaults })); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Initialize Form with Typebox Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `typebox` adapter for Typebox schemas. Define the schema outside the load function. ```typescript import { superValidate } from 'sveltekit-superforms'; import { typebox } from 'sveltekit-superforms/adapters'; import { Type } from '@sinclair/typebox'; // Define outside the load function so the adapter can be cached const schema = Type.Object({ name: Type.String({ default: 'Hello world!' }), email: Type.String({ format: 'email' }) }); export const load = async () => { const form = await superValidate(typebox(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Hidden Form for Background Operations Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-multiple-forms-+page.md Implement a hidden form for background tasks like validation or data updates using `superForm`'s features. This example shows a username availability check. ```typescript // First the visible form const { form, errors, ... } = superForm(...); // The the hidden form const { submitting, submit } = superForm( { username: '' }, { invalidateAll: false, applyAction: false, multipleSubmits: 'abort', onSubmit({ cancel, formData }) { // Using the visible form data if (!$form.username) cancel(); formData.set('username', $form.username); }, onUpdated({ form }) { // Update the other form to show the error message $errors.username = form.errors.username; } } ); const checkUsername = debounce(300, submit); ``` -------------------------------- ### Basic Formsnap Integration with Superforms Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-formsnap-+page.md This snippet demonstrates a typical form structure using Formsnap components with Superforms. It includes fields for name, email, and password, along with descriptions and error handling. ```svelte
Be sure to use your real name. It's preferred that you use your company email. Ensure the password is at least 10 characters.
``` -------------------------------- ### Superform Initialization with Timer Options Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-timers-+page.md Initialize `superForm` with `delayMs` and `timeoutMs` to control loading timer behavior. `delayMs` should be positive and less than or equal to `timeoutMs`. ```typescript const { form, enhance, submitting, delayed, timeout } = superForm(data.form, { delayMs?: 500, timeoutMs?: 8000 }) ``` -------------------------------- ### Using fieldProxy for Form Field Updates Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-components-+page.md Demonstrates how to use `fieldProxy` to create a store that directly modifies a specific field in the Superform's `$form` store. ```svelte
Name: {$name}
``` -------------------------------- ### Populate Form from Database with Superforms Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Populate a form with data from a database in a SvelteKit load function. Ensure the data partially matches the schema. ```typescript import { error } from '@sveltejs/kit'; export const load = async ({ params }) => { // Replace with your database const user = await db.users.findUnique({ where: { id: params.id } }); if (!user) error(404, 'Not found'); const form = await superValidate(user, your_adapter(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Manually Validate Files from FormData Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Obtain FormData from the request to manually get and validate files if your validation library doesn't support them directly. Ensure the file field is handled correctly after validation. ```typescript import { message, fail } from 'sveltekit-superforms'; export const actions = { default: async ({ request }) => { const formData = await request.formData(); const form = await superValidate(formData, zod(schema)); if (!form.valid) return fail(400, { form }); const image = formData.get('image'); if (image instanceof File) { // Validate and process the image. } return message(form, 'Thank you for uploading an image!'); } }; ``` -------------------------------- ### Creating a String Proxy Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Initializes a stringProxy for a string schema field, offering options to convert empty strings to null or undefined. ```typescript import { superForm, stringProxy } from 'sveltekit-superforms'; let { data } = $props(); const { form } = superForm(data.form); const proxy = stringProxy(form, 'field', { options }); ``` -------------------------------- ### Explicit Default for Union Types Source: https://github.com/rainypixel/superform-docs/blob/main/docs/+page.md When using multi-type unions, an explicit default value is required, or one of the union types must have a default. This example demonstrates setting a default for a union of number and string. ```typescript const schema = z.object({ either: z.union([z.number(), z.string()]).default(123), fish: z.enum(['Salmon', 'Tuna', 'Trout']) // Default will be 'Salmon' }); ``` -------------------------------- ### Superform onError Event Example Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-events-+page.md Utilize onError to catch SvelteKit errors. The result.error object's shape varies based on the error type. This snippet shows setting a message store with the error message. ```typescript onError: (({ result }) => void) | 'apply' ``` ```typescript const { form, enhance, message } = superForm(data.form, { onError({ result }) { $message = result.error.message || "Unknown error"; } }); ``` ```typescript onError: () => {} ``` -------------------------------- ### Creating a Date Proxy Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Initializes a dateProxy for a Date schema field, enabling custom string formatting for the proxied date. ```typescript import { superForm, dateProxy } from 'sveltekit-superforms'; let { data } = $props(); const { form } = superForm(data.form); const proxy = dateProxy(form, 'field', { options }); ``` -------------------------------- ### Date Proxy Options Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Lists format options for dateProxy, including date, time, datetime, UTC, and local time conversions, along with empty value handling. ```typescript { format: // Extract the part of the date as a substring: | 'date' | 'datetime' | 'time' // Convert the date to UTC: | 'date-utc' | 'datetime-utc' | 'time-utc' // Convert the date to local time: | 'date-local' | 'datetime-local' | 'time-local' // The default ISODateString: | 'iso' = 'iso'; empty?: 'null' | 'undefined'; taint?: boolean | 'untaint' | 'untaint-form'; } ``` -------------------------------- ### Enum Default for Select/Radio Inputs Source: https://github.com/rainypixel/superform-docs/blob/main/docs/+page.md To prevent any option from being initially selected in radio buttons or select menus using enums, set the default value to an empty string and cast it. This example shows how to achieve this for a fish enum. ```typescript const schema2 = z.object({ fish: z.enum(['Salmon', 'Tuna', 'Trout']).default('' as 'Salmon') }); ``` -------------------------------- ### Dynamically Switching Validation Schemas Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-client-validation-+page.md Demonstrates how to dynamically switch validation schemas using the options object, useful for multi-step forms. Requires the full adapter, not a client-specific one. ```typescript import { valibot } from 'sveltekit-superforms/adapters'; import { schema, partialSchema } from './schema.js'; const { form, errors, enhance, options } = superForm(data.form, { // Validate the first step of the form validators: valibot(partialSchema) }); // When moving to the last step of the form options.validators = valibot(schema) ``` -------------------------------- ### Custom Default Values with Zod Source: https://github.com/rainypixel/superform-docs/blob/main/docs/+page.md Customize default values for schema fields using Zod's `default` method. This example shows how to prevent a number field from defaulting to 0 and ensure a boolean checkbox is unchecked by default. ```typescript const schema = z.object({ age: z.number().positive().default('' as unknown as number), agree: z.literal(true).default(false as true) }); ``` -------------------------------- ### Use Form Component in Page Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-components-+page.md Import and use your reusable form component in the main page, passing the form data obtained from the load function. ```svelte ``` -------------------------------- ### Simplified Superforms Imports Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-whats-new-v2-+page.md Import core functionalities and adapters directly from 'sveltekit-superforms'. `SuperDebug` is now the default export. ```typescript import { superForm, superValidate, dateProxy } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import SuperDebug from 'sveltekit-superforms'; ``` -------------------------------- ### Render Primitive Array Inputs Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-nested-data-+page.md Use an `#each` loop to render multiple input fields for an array of primitive values. Ensure each input has the same `name` attribute as the schema field to allow Superforms to populate the array correctly. ```svelte
Tags
{#if $errors.tags?._errors}
{$errors.tags._errors}
{/if} {#each $form.tags as _, i}
{#if $errors.tags?.[i]} {$errors.tags[i]} {/if}
{/each}
``` -------------------------------- ### SuperForm Initialization with Client Validation Options Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-client-validation-+page.md Initializes SuperForm with options for client-side validation, including validators, validation method, and custom validity. ```typescript const { form, enhance, constraints, validate, validateForm } = superForm(data.form, { validators: ClientValidationAdapter | 'clear' | false, validationMethod: 'auto' | 'oninput' | 'onblur' | 'onsubmit' = 'auto', customValidity: boolean = false }) ``` -------------------------------- ### Displaying a Simple Form Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use this Svelte component to render a basic HTML form. Ensure input fields have a `name` attribute for proper data binding. The `superForm` function is required on the client-side for this to work. ```svelte
``` -------------------------------- ### String Proxy Options Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Details options for stringProxy, specifically the 'empty' option to map empty strings to 'null' or 'undefined'. ```typescript { empty: 'null' | 'undefined'; taint?: boolean | 'untaint' | 'untaint-form'; } ``` -------------------------------- ### Load Initial Data with +page.ts for SPA Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-spa-+page.md Use +page.ts to fetch initial data from an external API for a SPA route. This data is then used to initialize the Superforms form. ```typescript import { error } from '@sveltejs/kit'; import { superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { z } from 'zod'; export const _userSchema = z.object({ id: z.number().int().positive(), name: z.string().min(2), email: z.string().email() }); export const load = async ({ params, fetch }) => { const id = parseInt(params.id); const request = await fetch( `https://jsonplaceholder.typicode.com/users/${id}` ); if (request.status >= 400) throw error(request.status); const userData = await request.json(); const form = await superValidate(userData, zod(_userSchema)); return { form }; }; ``` -------------------------------- ### Import SuperDebug (Svelte 5 Rune) Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-super-debug-+page.md Import the SuperDebug component for use in Svelte 5 projects utilizing runes. ```ts import SuperDebug from 'sveltekit-superforms/SuperDebug.svelte'; ``` -------------------------------- ### Initialize Form with Effect Schema Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-get-started-[...lib]-+page.md Use the `effect` adapter for Effect Schemas. Define the schema outside the load function. ```typescript import { superValidate } from 'sveltekit-superforms'; import { effect } from 'sveltekit-superforms/adapters'; import { Schema } from 'effect'; const emailRegex = /^[^@]+@[^@]+.[^@]+$/; const schema = Schema.Struct({ name: Schema.String.annotations({ default: 'Hello world!' }), email: Schema.String.pipe( Schema.filter((s) => emailRegex.test(s) || 'must be a valid email', { jsonSchema: { format: 'email' } }) ) }); export const load = async () => { const form = await superValidate(effect(schema)); // Always return { form } in load functions return { form }; }; ``` -------------------------------- ### Returning Files in Form Actions with Superforms Helpers Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-files-+page.md Illustrates how to use Superforms' `message`, `setError`, and `fail` functions to correctly handle form data containing files. These functions automatically manage file serialization. ```typescript import { message, setError, fail } from 'sveltekit-superforms'; // message, setError and the Superforms fail handles this automatically: if (!form.valid) return fail(400, { form }); return message(form, 'Posted OK!'); return setError(form, 'image', 'Could not process file.'); ``` -------------------------------- ### Creating an Integer Proxy Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Initializes an intProxy for an integer form field. Useful when Svelte's default numeric input binding is insufficient. ```typescript import { superForm, intProxy } from 'sveltekit-superforms'; let { data } = $props(); const { form } = superForm(data.form); const proxy = intProxy(form, 'field', { options }); ``` -------------------------------- ### Handle Form Actions with Flash Messages Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-flash-messages-+page.md Use `setFlash` to display messages when staying on the same page after a form validation failure. Use `redirect` to send a message with a redirect to another page upon successful submission. ```typescript import { redirect, setFlash } from 'sveltekit-flash-message/server'; import { fail } from '@sveltejs/kit'; export const actions = { default: async ({ request, cookies }) => { const form = await superValidate(request, your_adapter(schema)); if (!form.valid) { // Stay on the same page and set a flash message setFlash({ type: 'error', message: "Please check your form data." }, cookies); return fail(400, { form }); } // TODO: Do something with the validated form.data // All ok, redirect with a flash message on another page redirect('/posts', { type: 'success', message: "Post created!" }, cookies); } }; ``` -------------------------------- ### superValidate with Initial Data Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Demonstrates calling superValidate to populate a form with initial data, such as from a database or request parameters. The data is passed as the first argument, followed by the adapter. ```typescript superValidate( data: | RequestEvent | Request | FormData | URL | URLSearchParams | Partial | null | undefined, adapter: ValidationAdapter, options?: SuperValidateOptions ): Promise> ``` -------------------------------- ### Integer Proxy Options Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-api-+page.md Defines options for intProxy, including handling of empty values and initial zero values. ```typescript { empty?: 'null' | 'undefined' | 'zero'; initiallyEmptyIfZero?: boolean; taint?: boolean | 'untaint' | 'untaint-form'; } ``` -------------------------------- ### Initialize Form with Defaults in SPA Source: https://github.com/rainypixel/superform-docs/blob/main/docs/routes-concepts-spa-+page.md Use the 'defaults' function to set initial schema values for a SPA form without needing a +page.ts file. The 'validators' option must be set for validation to work. ```typescript import { superForm, defaults } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import { loginSchema } from './schemas'; // Assuming loginSchema is defined elsewhere const initialData = { name: 'New user' }; const { form, errors, enhance, validateForm } = superForm( defaults(initialData, zod(loginSchema)), { SPA: true, validators: zod(loginSchema) // ... } ); validateForm({ update: true }); ```