this week I'm having a weird error into my Nuxt app, it's a small app, it's only a landing page with a register form for an event, I worked on this last week and I published it and it works fine. Now, I have to add some modifications into the register form, nothing complex, but when I ran the project locally, without update anything, and I'm getting now a hydration error into the fields 😢. Again, it's too weird for me because I don't update or change anything, Im running the exactly code version that is published, and if I run the build and preview cmd, I'm having the same error.
Now, the code:
Into the form I'm using this stack:
In my component I do this:
const registerFormStore = useRegisterFormStore();
const validationSchema = toTypedSchema(
object({
[DocumentFormFields.DOCUMENT_ID]: z
.string({ required_error: 'Ingresa tu documento de identificación' })
.min(6, 'error message')
.max(15, 'error message')
.transform((value) => value.trim().toLocaleUpperCase())
.default(registerFormStore.personalInfo.documentId || '')
})
);
const { errors, handleSubmit, defineField, setErrors } = useForm({
validationSchema
});
const formValues = reactive({
documentId: defineField<DocumentFormFields.DOCUMENT_ID, string>(DocumentFormFields.DOCUMENT_ID)[0]
});
<form class="flex flex-col gap-5" @submit.prevent="onSubmitForm">
<div class="flex flex-col gap-2">
<label for="documentId" class="font-medium">Document Label</label>
<IconField icon-position="left">
<InputIcon class="pi pi-id-card" />
<InputText
id="documentId"
v-model="formValues.documentId"
placeholder="Placeholder text"
class="w-full"
maxlength="15"
:disabled="isLoading"
:invalid="Boolean(errors[DocumentFormFields.DOCUMENT_ID])"
/>
</IconField>
<transition name="fade">
<small v-if="errors[DocumentFormFields.DOCUMENT_ID]" class="text-sm text-danger">
{{ errors[DocumentFormFields.DOCUMENT_ID] }}
</small>
</transition>
</div>
</form>
and now I'm having the hydration error:
[Vue warn]: Hydration attribute mismatch on <input class=​"p-inputtext p-component w-full" id=​"documentId" placeholder=​"Escribe tu documento de identidad" maxlength=​"15" data-pc-name=​"inputtext" data-pc-section=​"root">​
- rendered on server: (not rendered)
- expected on client: value=""
Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead.
You should fix the source of the mismatch.
at <InputText id="documentId" modelValue="" onUpdate:modelValue=fn ... >
at <IconField icon-position="left" >
at <DocumentValidationForm key=3 >
at <RegistrationComponent key=2 >
at <FormSection>
at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
at <Anonymous key="/" vnode= {__v_isVNode: true, __v_skip: true, type: {…}, props: {…}, key: null, …} route= {fullPath: '/', hash: '', query: {…}, name: 'index', path: '/', …} ... >
at <RouterView name=undefined route=undefined >
at <NuxtPage>
at <App key=3 >
at <NuxtRoot>
And later, all the other steps into my form are broken, for example, when I change to the next step, I load the documentId and the username, and the fields now are broken and don't take the default value:
const validationSchema = toTypedSchema(
object({
[PersonalInfoFormFields.NAME]: z
.string({ required_error: 'error text' })
.min(2, 'error text')
.max(100, 'error text')
.transform((value) => value.trim())
.default(registerFormStore.personalInfo.name || ''),
[PersonalInfoFormFields.EMAIL]: z
.string({ required_error: 'error text' })
.email('error text')
.transform((value) => value.trim().toLocaleLowerCase())
.default(registerFormStore.personalInfo.email || '')
The data into the store is OK, but into the fields not
Look that all the fields are undefined when it should be with an empty string
I already work and search about this error but I don't have any idea why it's happening. 🥲 I'm not sure if it's related with Pinia, because the console of store installed
but the weird think is that I do not update any library version or similar.
Any help is welcome!, thanks in advance.
I found that the error was caused for different things:
Using Date.now()
as initial value in some ref()
const, example const myVar = ref(Date.now());
DON'T do that, initialize the ref
in zero and later into the onMounted
set the value myVar.value = Date.now()
I was using refine
for validate two form fields:
const validationSchema = toTypedSchema(
object({
[PersonalInfoFormFields.EMAIL]: z
.string({ required_error: 'error message' })
.email('error message')
.transform((value) => value.trim().toLocaleLowerCase())
.default(registerFormStore.personalInfo.email || ''),
[PersonalInfoFormFields.REPEAT_EMAIL]: z
.string({ required_error: 'error message' })
.email('error message')
.transform((value) => value.trim().toLocaleLowerCase())
.default('')
}).refine(({ email, repeatEmail }) => email === repeatEmail, {
message: 'error message',
path: [PersonalInfoFormFields.REPEAT_EMAIL]
})
);
If I remove this (the refine
function), all works fine, otherwise, I have the error that the fields are in undefined.
I was able to resolve my error with those steps.
Special thanks to @kissu that help me to found the errors