Upgrade to Conform V1

Kent C. Dodds
Kent C. Dodds

Edmund Hung, the author of Conform, has released version 1 of the fantastic form library. In this video, we walk through the migration process and highlight the changes. The upgrade to Conform V1 brings some exciting new features, such as the submission.reply API, simplified form setup, and improved error handling. Join us as we explore the updates and learn how to make the most of Conform V1.


00:00 It's a beautiful day here Edmund Hung the author of Conform Which is a fantastic form library that we use in the Epic Stack and in Epic Web has released version 1 so we have an official version 1 release of Conform and I am excited to upgrade all of our stuff. But I want to walk through some of the migration stuff so that you can have this and that like it can be useful to you until I can re-record all the videos that use Conform. Luckily for us there's actually not a ton of changes and Conform has this awesome guide that will kind of walk you through some of the changes So now we require react 18 or higher that shouldn't be an issue for most of you all Lots of the helpers have now been moved from the conform object that we import into individual utilities, which is also kind of nice. We weren't ever using the validation, undefined or validation skip stuff. So we don't need to worry about that change.

01:00 And the type option is now required on get input props. That's a pretty easy thing to address. And yeah, we have a description option named to ARIA described by we actually never used that either because we're using error messages and things like that too. So the form setup changes a little bit. Now we're using get form props before we were spreading the form dot props.

01:25 We'll look at some of those changes here in a little bit. And then we also have the use field set use field list. Those hooks have now been removed and instead we have simple functions that we call, which, and they're called off of the fields that come from use form, which actually I like a lot because it associates the form and all of its fields and stuff to the those field sets. So that's a really nice change. Again not really like a super conceptual change or anything just solidified the API a little bit to something a little more ergonomic.

02:02 Okay so both the validate and list exports are merged into the form metadata object. So here we've got our fields, we have our field list, and then we're iterating over the tasks to get those. And then we have this add and like you can have add and remove and stuff like that APIs. So here we can say, hey, I want the button props for a button that inserts into this field list. So that is now been merged as part of that form metadata object there.

02:32 So again, another like relatively small change. And then, yeah, again, these are all just moved from the field set list onto the form directly, which, yeah, pretty simple migration there. Schema stuff has changed a little bit we're using Zod and so instead of parse it's going to be parse with Zod just a name change there and get field set constraint is now get Zod constraint that's also fine does the exact same thing so there's not really a significant change there. And then submission handling is interesting. So now for us this will be parsed with Zod to get our submission.

03:11 And we have if the submission status is not success then we're going to use this new submission.reply API to send back all of the data that Zon or that Conform needs to display errors or whatever else needs to be shown in there. We can also use that to determine the status for HTTP code. So if there was an error, then we get a 400. If it's not success, it could be that we're validating as the user's typing or something. So that would technically be a 200.

03:43 If like we're submitting, it was there's no error. It's just like, yes, it is still valid. And so in that case, that status is still going to be a 200. So this kind of simplifies some of the boilerplate that we had before this submission reply, especially that's I helped with that API a little bit that's quite nice. And then here we're just doing like our own application logic right.

04:07 So if we have something wrong in our application logic then we can actually then send a reply and say hey here's the form errors there is like some error with the database or whatever. Here's the field errors. This specific address was already in the database or whatever doesn't happen as part of the transformation in your parsing process is something that you can add as part of the reply. So you get to add additional error information as part of this. And then you can also hide fields.

04:39 So when you reply, like let's say you're doing a login form or onboarding form, it takes a password and stuff and something is wrong with the password. You don't want to send that password back over the wire and so you can just hide those fields. This is actually something that we were doing in the Epic stack ourselves. We no longer have to do it that way which is quite nice also. And then ultimately we can if things are successful we can reply and actually say hey reset the form So clear out all the form fields that was successful.

05:08 They're going to enter in a new one or whatever. So that's also nice. That's a new feature that we weren't using before. Now we also have use input control. So we are using this in the Epic stack, but I never, we didn't really address it too much in Epic web in the workshops.

05:24 So this isn't going to affect any of those lessons or anything, but using input control is a new hook that replaces the use input event hook and it simplifies some things and just kind of changes some things and we'll actually see that in the diff. So most like from this you can tell most things that happened with conform were just like renaming the API moving things around And probably the most exciting thing is this submission reply API that both reduces boilerplate and makes it much easier to have extra error messages that you're not going to get just from parsing the Zod schema. So luckily for us, Edmund was kind enough to actually make a pull request to the Epic stack. So we're going to walk through this together and talk about a couple of the changes. Lots of these things will be like pretty quick.

06:16 So use input event has now been renamed to use input control and we no longer need to do use refs with that anymore which is kind of nice. And right down here we're going to take the name form and value as props to our buttons now and those are going to ultimately be used as part of the props that we pass to the underlying checkbox right here. So the basically the use input event or what used to be the use input event is now use input control allows us to integrate our radix checkbox with conform. So focus management is managed properly and keeping the value up to date and initialize properly, it happens properly. So that's what use input control is doing here.

07:07 It's just taking the place of use input event. There aren't a ton of differences between the old API and the new one. We don't have a ref anymore. We don't have an on focus. But and we are passing the name of the button that is being associated to our checkbox as well as the ID of the form if the form is going to be different for the particular checkbox.

07:36 And then we can set the initial value there. And then from there, it's all just changing from what used to be the control to the thing we renamed as index or as input, and then managing our focus and blur events there. Again, not something that you actually do a whole lot, but that is really useful for situations where you've got a component that needs to integrate or needs to render form elements and things. It's just an integration layer. Okay, so the rest of this is actually pretty straightforward.

08:07 So now we're just kind of renaming things, moving things around a little bit. Now it's parse with Zodd instead of just parse. We get rid of some of this boilerplate, which is quite nice. And then we can just do submission.reply and this is a particularly easy one because it's just the theme switcher and here we're parsing with Zod. We are doing this in the client to make sure that when we're doing the optimistic update that we're parsing that submission so we can get that theme value.

08:36 And then instead of last submission with this use form, it's now last result, which I actually like that quite a bit. And then we're also actually returning right here instead of calling this submission right here we're just returning the result itself and so now it's venture data result and you're going to see this same thing repeated over and over again again also this is form dot props turns into get form props and pass the form. And we no longer need to render the error list here. That's in this case, there's actually no errors that could be sent for this particular form. Okay.

09:13 So then we also have get form props, get input props coming from Conform to React, and then Zod specific utilities for the Zod parsing and stuff. Again, just renaming stuff, reducing the boilerplate here. So now instead of, is the intent submit? Okay, if it's not, do this. Is the value there?

09:31 Oh, it's not, then do this. It's all just in one thing. So if it's not a successful submission, then we'll just reply and it could be that they were just doing validation as the users typing. And so that's that could be what is happening here. So it's not necessarily an error or it could actually be an error.

09:48 In either case, it's not a successful submission because it's not a finished submission. So we are handling the exact same use case as the previous boilerplate, but this is more terse and all happens in a single if statement, which is quite nice. We did actually investigate looking for a way to simplify this even further and reduce even more boilerplate, but there's not really a great way to do that. So this is what we have here. Okay, so then before for us to have a form message you would have submission dot error and then empty string which actually resembles the web platform for form error messages But it was a little confusing and so that's one of the reasons I'm so jazzed about this submission reply API where we can just say here are the form errors much more straightforward.

10:38 Okay, and then again just a couple of name changes here. So it's constraint is the Zod constraint thing instead of submission. It's results. We're sending back results instead of calling it submission now. Again, parse with Zod, all of that stuff.

10:51 And instead of form.props, it's get form props. And then here's the other place where this thing was renamed. Conform.input is now get input props. And the type needs to be specified for everything which yeah that works fine. And yeah now the form.status that is coming from our form up here instead of the forgot password data status stuff.

11:18 So Conform is now able to give us a little bit more information about the status here. And yeah, that's quite nice. Okay, cool. So some more renames of stuff, just reformatting some things right here. One change here is the intent.

11:36 So the intent was a little bit of a over overloaded term a bit. So now this intent here Let's expand this a little bit further. Yeah, there it is. Yeah. So the intent still comes in as part of our schema input and as part of this transform, we're just checking.

11:56 Hey, is this intent the thing that the user is doing? This is something that's given to us from conform. Are you just trying to are you trying to submit the form or are you trying to do validation while they're typing or whatever. And so now if the intent is null then that means that they are actually submitting the form. And so if it's not null, then they're not actually submitting.

12:19 And so we exit early from actually avoiding like creating the session and stuff like that. So this is what this means is if they are just validating as they type or validating on blur or whatever, then go ahead and return the transformed data already and don't bother creating the session. So we talk all about that in the workshops. Here's one nice thing we no longer have to do deleting the password from that payload if we send that back because we have hide fields right there in that submission reply. So that's also quite nice.

12:55 Again, all of this stuff can be combined into a single submission reply and we can specify the status code based on whether the reason we're replying is because it's an error. So that is also nice. Some more renames there. Nothing too interesting there. Some more renames of that stuff.

13:14 And going to the form status instead of the data that came back. Awesome. And that form status is coming because we send the reply and it has whether or not there was an error or something there. So that's quite nice. Okay.

13:29 I'm just looking. Everything here looks pretty much the same. I don't think that there's actually anything else that's different. All the rest of this is going to be the same sort of thing that we've already seen. So that hopefully gives you a pretty good idea of what to expect with conform V1.

13:47 There are breaking changes but they are fairly minimal. Most of them are just like renaming APIs and stuff like that. The concepts are all the same. The progressive enhancement that you have loved from Conform since the very beginning, all the same. And I just, I super love this library as a library for helping us build better forms on our websites and I hope that you love this updated version Now here let's come down right here.

14:19 Yeah this was an indention change here as well. Yeah here we go. We're getting to the field list. I almost forgot about that. So we have use field list.

14:29 We had to pass the form ref and the field images that config that we got from our form. Now we just say fields images get field list and now we've got our image list. Again a relatively simple thing. We also are using the form provider that's that's another new thing. So this allows any components that are rendered within our form to access some of the config from the form.

14:55 So right here, yeah, we've got the note editor in here. And if we go further down, we'll see we have an image chooser. So this image chooser needs to be connected to that form. And so that form provider is going to provide that information. So then we can get the field set for this particular set of fields.

15:16 So that is another change. But from there like most things are still going to be relatively like pretty much the same and we no longer need to worry about refs which is also quite nice. Okay. I think that is everything. Then of course a package JSON change and boom we go to 1.0.

15:34 So there you go that is Conform 1.0. Congratulations to Edmund for a job well done and congratulations to us for having an even better library with better ergonomics and better awesome forms for our users. So hopefully that's helpful. We'll see you around the Internet.

More Tips