forms
Forms are where validation, error messages and double submits meet, and every team ends up rewriting them. This feature gives each remote a working contact form built on react-hook-form that you copy from and change.
What you get
Each remote gets a schema, a ContactForm component with a label, an input and an error message for every field, and a test. The shell gets nothing, and no package is shared: each remote installs its own copy of the libraries.
Add it
The command asks which schema library to use and defaults to zod. To skip the question:
What changed, in every remote:
The form library, its resolvers package and your validator are added as dependencies. The test file needs the testing feature.
Use it
The schema describes the fields and gives you the type of the values.
The form hands you validated values. The submit button stays disabled while your promise runs, so a double click sends once.
Nothing imports the example yet, so it costs nothing until you use it. When you do, load it on demand so the form library stays out of the remote's first load.
Configure it
How it works
The form uses standardSchemaResolver, which accepts any Standard Schema. The form code is identical for all three libraries, and only schema.ts differs.
The option is separate from the validator of env-t3, so the two can differ. One library across the project is one less thing to learn.
A validator inside a remote bundle is fine. What env-t3 keeps out of the browser is its own env file and runtime-config schema.
The test that comes with the form checks two things: errors show and nothing is sent when the values are wrong, and valid values are sent once even if the button is clicked twice.
Gotchas
- The arktype schema does not set custom messages, so its errors read like arktype's own. Add messages there if you want wording like the zod example.
- Server errors belong in
setError, inside your ownonSubmit. The example only shows validation. react-hook-formis not a shared singleton: forms hold no state two remotes need. Share data through the event bus, not through a form.- Mind the 10 KB default remote budget when you import the form eagerly.