---
url: https://formhaus.dev/migrate/0.14.md
description: >-
  Upgrade from Formhaus 0.13 to 0.14: time and hidden field types, sections,
  repeatable groups, FormNode[] fields arrays and item paths as error keys.
---

# Migrate to 0.14

0.14 adds the built-in `time` and `hidden` field types, [sections](/guide/sections) and [repeatable groups](/guide/groups), and reads definition format 1.1. Existing definitions keep their meaning. A definition that already used `time`, `hidden`, `section` or `group` for a custom type now gets the built-in behavior.

```bash
npm i @formhaus/core@^0.14 @formhaus/react@^0.14
npm i @formhaus/core@^0.14 @formhaus/vue@^0.14
```

Upgrade the server that runs `validateSubmission()` first, then the clients. Core 0.13 and older skip the fields inside a section and pass a group value through without checks.

## Changes

| Area | Old (0.13) | New (0.14) | Action |
|---|---|---|---|
| Definition | `time` was a custom type without checks | 24-hour `HH:mm` or `HH:mm:ss`; other values fail with "Enter a valid time" | Store 24-hour times, or rename your custom type |
| Definition | `hidden` was a custom type without checks | Checked as text; its errors are form-level errors | Store text values, or rename your custom type |
| Definition | `section` and `group` were custom types | Built-in containers with nested `fields` | Rename your custom type |
| Types | `FormStep.fields` and `FormDefinition.fields` were `FormField[]` | `FormNode[]`, a union of `FormField`, `FormSection` and `FormGroup` | Narrow with `isSection()` and `isGroup()` before reading field properties |
| Errors | Every error key was a field key | Item errors use paths such as `participants.1.email` | Map error keys through the path form when you match them to fields |
| Headless renderers | `visibleFields` listed everything to draw | `visibleNodes` holds the tree; `visibleFields` stays flat | Render sections and groups from `visibleNodes` |
| Validation | Options with a repeated `value` passed `checkDefinition()` and `FormEngine` | `checkDefinition()` and `FormEngine` reject them with `duplicate-option-value` | Give every option of a field a unique `value` |
| Cloud | `FormhausForm` and `@formhaus/core/cloud` used api.formhaus.dev | Default is api.formhaus.cc; api.formhaus.dev keeps working | Add `https://api.formhaus.cc` to your CSP `connect-src` if you use an allowlist |
| Format | `FORMAT_VERSION` was `"1.0"` | `"1.1"` | Set `"formatVersion": "1.1"` on definitions with sections or groups |

```ts
import { isGroup, isSection } from '@formhaus/core';

for (const node of step.fields) {
  if (isSection(node)) renderSection(node);
  else if (isGroup(node)) renderGroup(node);
  else renderField(node);
}
```
