> ## Documentation Index
> 
> Fetch the complete documentation index at: [/docs/llms.txt](/docs/llms.txt)
> 
> Use this file to discover all available pages before exploring further.

[Skip to main content](#content-area)

## 

[​

](#useformstate)

useFormState

Core form state management hook. Used internally by `OSForm` — exposed for advanced custom renderers.

```
import { useFormState } from '@osforms/react';

const [state, actions] = useFormState(schema, endpoint, onComplete, onError);
```

### 

[​

](#parameters)

Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `schema` | `FormSchema | null` | Form schema. Pass `null` while loading. |
| `endpoint` | `string` | Submission URL (`https://osforms.com/api/v1/f/{slug}`) |
| `onComplete` | `() => void` | Called after successful submission |
| `onError` | `(error: Error) => void` | Called when submission fails |

### 

[​

](#formstate)

FormState

| Field | Type | Description |
| --- | --- | --- |
| `answers` | `Record<string, unknown>` | Current field values keyed by field ID |
| `currentIndex` | `number` | Index of the active field in `visibleFields` |
| `direction` | `'forward' | 'backward'` | Last navigation direction (use for slide animations) |
| `errors` | `Record<string, string>` | Validation errors per field ID. `_form` key holds submission errors. |
| `isSubmitting` | `boolean` | `true` while the POST is in flight |
| `isComplete` | `boolean` | `true` after successful submission |
| `showWelcome` | `boolean` | `true` when the welcome screen should be shown |

### 

[​

](#formstateactions)

FormStateActions

| Field | Type | Description |
| --- | --- | --- |
| `setAnswer` | `(fieldId, value) => void` | Update a field’s value and clear its error |
| `advance` | `(overrideValue?) => boolean` | Validate current field and advance. Returns `false` if validation failed. |
| `back` | `() => void` | Move to the previous field |
| `submit` | `() => Promise<void>` | Validate all fields and POST to the endpoint |
| `startForm` | `() => void` | Dismiss the welcome screen |
| `visibleFields` | `FormField[]` | Fields visible based on current answers and conditional logic |
| `currentField` | `FormField | undefined` | The field at `state.currentIndex` |

### 

[​

](#example-custom-renderer)

Example: custom renderer

```
import { useFormState, useFormSchema } from '@osforms/react';

function MyForm({ formSlug }: { formSlug: string }) {
  const { schema, loading } = useFormSchema(formSlug);
  const [state, actions] = useFormState(
    schema,
    `https://osforms.com/api/v1/f/${formSlug}`,
    () => alert('Submitted!'),
    (err) => alert(err.message)
  );

  if (loading) return <p>Loading...</p>;
  if (state.isComplete) return <p>Thanks!</p>;

  const field = actions.currentField;
  if (!field) return null;

  return (
    <div>
      <label>{field.label}</label>
      <input
        value={(state.answers[field.id] as string) ?? ''}
        onChange={(e) => actions.setAnswer(field.id, e.target.value)}
      />
      {state.errors[field.id] && <p>{state.errors[field.id]}</p>}
      <button onClick={() => actions.advance()}>Next</button>
    </div>
  );
}
```

* * *

## 

[​

](#useformschema)

useFormSchema

Fetches a form schema from the osforms API.

```
import { useFormSchema } from '@osforms/react';

const { schema, formName, redirectUrl, loading, error } = useFormSchema(
  'your-form-slug',
  'https://osforms.com' // optional baseUrl override
);
```

### 

[​

](#return-value)

Return value

| Field | Type | Description |
| --- | --- | --- |
| `schema` | `FormSchema | null` | Parsed form schema. `null` while loading. |
| `formName` | `string` | Display name of the form |
| `redirectUrl` | `string` | Redirect URL configured in form settings |
| `loading` | `boolean` | `true` while the fetch is in flight |
| `error` | `string | null` | Error message if the fetch failed |

Fetches from: `{baseUrl}/api/v1/f/{formId}/schema`

⌘I