# Add form fields

To add a field to your form, you can use the <Link href="/svelte/api/Field/">`Field`</Link> component or the <Link href="/svelte/api/useField/">`useField`</Link> rune. Both are headless and provide access to field state for building your form UI.

## Field component

The <Link href="/svelte/api/Field/">`Field`</Link> component has two mandatory properties: `of` which accepts the form store, and `path` which specifies which field to connect. If you use TypeScript, you get full autocompletion for the path based on your schema.

### Snippet syntax

Use Svelte's `{#snippet children(field)}` syntax to define how the field should render. The field store parameter includes the current value, error messages, and props to spread onto your input element.

```svelte
<script lang="ts">
  import { createForm, Field, Form } from '@formisch/svelte';
  import * as v from 'valibot';

  const LoginSchema = v.object({
    email: v.pipe(v.string(), v.email()),
    password: v.pipe(v.string(), v.minLength(8)),
  });

  const loginForm = createForm({
    schema: LoginSchema,
  });
</script>

<Form of={loginForm}>
  <Field of={loginForm} path={['email']}>
    {#snippet children(field)}
      <input {...field.props} value={field.input} type="email" />
    {/snippet}
  </Field>
  <Field of={loginForm} path={['password']}>
    {#snippet children(field)}
      <input {...field.props} value={field.input} type="password" />
    {/snippet}
  </Field>
  <button type="submit">Login</button>
</Form>
```

> **Important:** If you plan to set initial values with `initialInput` or programmatically control field values using methods like <Link href="/methods/api/setInput/">`setInput`</Link> or <Link href="/methods/api/reset/">`reset`</Link>, you must make your fields controlled by setting the appropriate attributes (like `value`, `checked`, or `selected`). See the <Link href="/svelte/guides/controlled-fields/">controlled fields</Link> guide to learn more.

### Headless design

The <Link href="/svelte/api/Field/">`Field`</Link> component does not render its own UI elements. It is headless and provides only the data layer of the field. This allows you to freely define your user interface. You can use HTML elements, custom components or an external UI library.

### Path array

The `path` property accepts an array of strings and numbers that represents the path to the field in your schema. For top-level fields, it's simply the field name wrapped in an array:

```svelte
<Field of={loginForm} path={['email']}>
  {#snippet children(field)}
    <input {...field.props} value={field.input} type="email" />
  {/snippet}
</Field>
```

For nested fields, the path reflects the structure of your schema:

```svelte
<!-- For a schema like: v.object({ user: v.object({ email: v.string() }) }) -->
<Field of={form} path={['user', 'email']}>
  {#snippet children(field)}
    <input {...field.props} value={field.input} type="email" />
  {/snippet}
</Field>
```

### Type safety

The API design of the <Link href="/svelte/api/Field/">`Field`</Link> component results in a fully type-safe form. For example, if you change your schema, TypeScript will immediately alert you if the path is invalid. The field state is also fully typed based on your schema, giving you autocompletion for properties like `field.input`.

## useField rune

For very complex forms where you create individual components for each form field, Formisch provides the <Link href="/svelte/api/useField/">`useField`</Link> rune. It allows you to access the field state directly within your component logic.

```svelte
<script lang="ts">
  import { useField } from '@formisch/svelte';
  import type { FormStore } from '@formisch/svelte';
  import * as v from 'valibot';

  type EmailInputProps = {
    form: FormStore<v.GenericSchema<{ email: string }>>;
  };

  let { form } = $props<EmailInputProps>();

  const field = useField(form, { path: ['email'] });
</script>

<div>
  <input {...field.props} value={field.input} type="email" />
  {#if field.errors}
    <div>{field.errors[0]}</div>
  {/if}
</div>
```

### When to use which

- **Use <Link href="/svelte/api/Field/">`Field`</Link> component**: When defining multiple fields in the same component. It ensures you don't accidentally access the wrong field store.
- **Use <Link href="/svelte/api/useField/">`useField`</Link> rune**: When creating field components for single fields. It allows you to access field state in your component logic.

The <Link href="/svelte/api/Field/">`Field`</Link> component is essentially a thin wrapper around <Link href="/svelte/api/useField/">`useField`</Link> that allows you to access the field state within your snippet code.

## Field store

The field store provides access to the following properties:

- `props`: Props to spread onto your input element (includes event handlers, name attribute, and `autofocus` to automatically focus fields with errors).
- `input`: The current input value of the field.
- `errors`: An array of error messages if validation fails.
- `isTouched`: Whether the field has been touched.
- `isDirty`: Whether the current input differs from the initial input.
- `isValid`: Whether the field passes all validation rules.
- `onInput`: Sets the field input value programmatically. Use this when the field cannot be connected to a native HTML element (e.g., complex custom inputs or component libraries that don't expose the underlying element).

## Next steps

Now that you know how to add fields to your form, continue to the <Link href="/svelte/guides/input-components/">input components</Link> guide to learn about creating reusable input components for your forms.
