### 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
```
--------------------------------
### 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
```
--------------------------------
### 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
```
--------------------------------
### 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
```
--------------------------------
### 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
```
--------------------------------
### 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
```
--------------------------------
### 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 });
```