v1.14.0
Breaking Changes (Future APIs)
-
The
intendedValueoption in the report helper has been renamed tovalueand now works as thedefaultValuewhen resetting the form. Previously, this option was ignored when resetting and the form would always reset to the default value. You can now use thevalueoption to update or reset forms to a specific value. (#1079)// Update form to a specific value after submission return { result: report(submission, { value: updatedValue, }), }; // Reset form to a specific value after submission return { result: report(submission, { reset: true, value: defaultValue, }), };
-
parseSubmissionnow strips empty values by default. This makes it easier to work with schemas directly (withoutcoerceFormValue) since you no longer need extra validation like.min(1)for required fields. You can setstripEmptyValues: falseto preserve empty values if needed. (#1110)const formData = new FormData(); // Empty text input formData.append('name', ''); // Empty file input formData.append('files[]', new File([], '')); parseSubmission(formData); // { payload: {} } parseSubmission(formData, { stripEmptyValues: false }); // { payload: { name: '', files: [new File([], '')] } }
What's Changed
-
Schema-first future
useFormhook with improved type inference (#1106)The
schemaoption is now promoted to the first argument ofuseFormfor better type inference:// Before: schema in options const { form, fields } = useForm({ schema: mySchema, onSubmit(event, { value }) { // value type inference could be inconsistent }, }); // After: schema as first argument const { form, fields } = useForm(mySchema, { onSubmit(event, { value }) { // value is fully typed based on your schema }, });
onValidateis now required when not using a schemaEither(Relaxed the type to allow both to be optional in v1.14.1)onSubmitorlastResultmust be provided
The old API with
schemain options still works but is now deprecated. It will be removed in the next minor release. -
Fixed
parseSubmissionarray handling for entries ending with[]. Previously, when multiple form entries had the same name ending with[](e.g.,todos[]), all items were incorrectly pushed as a single nested array element. Now they are correctly spread as individual array items. (#1108)const formData = new FormData(); formData.append('todos[]', 'Buy milk'); formData.append('todos[]', 'Walk dog'); formData.append('todos[]', 'Write tests'); parseSubmission(formData); // Before (incorrect): { todos: [['Buy milk', 'Walk dog', 'Write tests']] } // After (correct): { todos: ['Buy milk', 'Walk dog', 'Write tests'] }
Improvements
- You can now import from
@conform-to/zod/v3if you need to work with v3 schema using zod v4. (Thanks @kesoji - #1090) - Fixed type inference for
getFieldset()with interface declarations (#1097) - Moved
lastResultlogic from an effect to the render phase. Your form component may now render twice within a single lifecycle when needed, but state updates that previously spanned two separate lifecycles now complete in one. (#1103) - Improved
FormOptionsandValidationAttributestypes compatibility withexactOptionalPropertyTypessetting in tsconfig. (#1105)
Full Changelog: v1.13.3...v1.14.0