nuxt ui form apply error on specific field
so i have a nuxt ui form with a signupschema but my api checks for compromised passwords so i want to display a zod like error on the password field if my api returns this. what's the cleanest way to do this
53 Replies
Hi @WiFi Plug. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To display an error on a specific field (e.g., the password field) in a Nuxt UI form when your API returns a custom error (like "compromised password"), you should use the exposed form instance methods, specifically
- Form Expose API
- Custom Validation and Error Handling ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
setErrors
. This allows you to programmatically set errors on individual fields after your API response, mimicking Zod-style errors.
Here's the cleanest approach:
1. Expose the form instance using useTemplateRef
.
2. On API response, if the password is compromised, call form.value.setErrors
with the appropriate error object for the password field.
Example
- The key is using form.value?.setErrors([{ name: 'password', message: '...' }])
to set the error on the password field after your API check.
- This approach works seamlessly with Zod or any schema validation, and integrates with Nuxt UI's error display system for fields.
References:- Form Expose API
- Custom Validation and Error Handling ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai should i bing :loading to my nuxt ui form loading being set to true while im doing my api call?
Let me check the knowledge base for you again. One moment! :books:
----------------------
You generally do not need to manually bind the
- By default, you do not need to manually bind
:loading
prop to your Nuxt UI form while performing an API call if you are using the default behavior. The Nuxt UI <UForm>
component has a loadingAuto
prop (enabled by default), which will automatically set all form elements to a loading/disabled state during the @submit
event. This means inputs will be disabled and loading indicators will show as appropriate while your async submit handler is running.
If you want to control the loading state manually (for example, if you have a more complex flow or want to show loading outside of the default submit lifecycle), you can use the :loading
prop and set it to true
while your API call is in progress. But for most use cases, the default loadingAuto
behavior is sufficient and recommended for simplicity Nuxt UI Form Props Nuxt UI Button Loading.
Summary:- By default, you do not need to manually bind
:loading
—loadingAuto
handles it.
- Use :loading
only if you need custom/manual control over the loading state.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai so this is properly implemented as clean as can be?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Your implementation is very close to best practices for a Nuxt UI form, but there are a few points to consider for maximum cleanliness and alignment with Nuxt UI conventions:
1. Form Loading State:
You are not using the
Displaying a general error with
Using
Your use of
Disabling the submit button when
- Add
- Nuxt UI Form Schema Validation
- Nuxt UI Button Loading
- Nuxt UI Form Expose ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
You are not using the
loading
or loading-auto
prop on your <UButton>
. By default, Nuxt UI forms handle loading automatically (loadingAuto
is true
), but to provide a better user experience, you should add the loading-auto
prop to your submit button. This will show a loading indicator and disable the button while the form is submitting, without needing to manage loading state manually (Button Loading).
2. Error Handling:Displaying a general error with
<UAlert>
is good. If you want to show field-specific errors (e.g., from your API), use the form's setErrors
method as discussed previously (Form Expose).
3. Validation:Using
:schema
and :state
is correct and recommended (Form Schema Validation).
4. Accessibility:Your use of
label
and name
on UFormField
is correct and ensures accessibility.
5. External Controls:Disabling the submit button when
!turnstileToken
is a good practice for external validation.
Summary:- Add
loading-auto
to your submit button for a better UX.
- Otherwise, your implementation follows Nuxt UI best practices for a clean and maintainable form.
If you want to handle field-specific errors from your API, remember to use the form's setErrors
method as shown in the previous answer.
References:- Nuxt UI Form Schema Validation
- Nuxt UI Button Loading
- Nuxt UI Form Expose ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai and the :disabled thing would work correctly to ensure it's disabled if no turnstile token but still disable it based on the form? this is the script part of my code is this optimal?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, your approach to disabling the submit button with
- Your use of
:disabled="!turnstileToken"
will ensure the button is disabled when there is no Turnstile token. However, this only covers the Turnstile check. If you want the button to also be disabled during form submission (i.e., while loading
is true
), you should combine both conditions:
But, if you use the loading-auto
prop on <UButton>
, Nuxt UI will automatically disable the button during form submission, so you only need to check for the Turnstile token:
This way, the button is:
- Disabled if there is no Turnstile token (!turnstileToken
)
- Automatically disabled and shows a loading indicator while the form is submitting, thanks to loading-auto
(Button Loading).
Summary:- Your use of
:disabled="!turnstileToken"
is correct for the Turnstile check.
- Add loading-auto
to <UButton>
for automatic disabling/loading during submission.
- You do not need to manually manage the loading
state for the button if you use loading-auto
.
This approach is optimal and aligns with Nuxt UI best practices for form and button state management Form Props Button Loading.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai ah so i could have removed my loading ref entirely, i just did that and it still works nicely with loading-auto on the form
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, that's correct! With
loading-auto
on the <UButton>
, Nuxt UI automatically manages the loading and disabled state of the button during form submission. You do not need to manually manage a loading
ref for this purpose—the form and button will handle it for you. This is the recommended and cleanest approach according to the Nuxt UI documentation Button Loading.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai and i removed this " turnstileToken.value = "";" instead relying on turnstile.value?.reset() is that fine since that should empty the ref
Let me check the knowledge base for you again. One moment! :books:
----------------------
I'm sorry, but the knowledge sources do not contain explicit information about the behavior of
turnstile.value?.reset()
and whether it will automatically clear the turnstileToken
ref in your specific implementation. If turnstile.value?.reset()
is designed to reset the token and update the bound v-model
, then removing turnstileToken.value = ""
should be fine. However, without documentation or source code confirming this behavior, I cannot state this with certainty. Please verify this behavior in your component or refer to the documentation for NuxtTurnstile
if available.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai what's the difference between ref and useTemplateRef when storing a reference to my form so i can set errors manually
Let me check the knowledge base for you again. One moment! :books:
----------------------
The main difference between
- Use
- Nuxt UI Form Expose
- Nuxt UI Table Expose
- Nuxt UI Carousel Expose
- Nuxt UI AuthForm Expose
- Nuxt UI Stepper Expose
- Nuxt docs update to useTemplateRef ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
ref
and useTemplateRef
when storing a reference to your form in Nuxt 3 (and Vue 3.5+) is that useTemplateRef
is the recommended way to reference a template ref for HTML elements or components, especially in <script setup>
. This is now the standard approach in Nuxt UI and other Nuxt/Vue documentation.
- ref
is a general-purpose reactivity primitive for storing any reactive value.
- useTemplateRef
is specifically designed for template refs, making it easier and more type-safe to access component or element instances referenced in your template.
For example, to access your form instance and call methods like setErrors
, you should use:
And in your template:
This approach is shown throughout the Nuxt UI documentation for accessing component APIs, such as forms, tables, carousels, etc. (Nuxt UI Form Expose).
In summary:- Use
useTemplateRef
for template refs in Nuxt 3/Vue 3.5+ for better integration and type safety.
- ref
is more generic and not tailored for template refs in this context.
References:- Nuxt UI Form Expose
- Nuxt UI Table Expose
- Nuxt UI Carousel Expose
- Nuxt UI AuthForm Expose
- Nuxt UI Stepper Expose
- Nuxt docs update to useTemplateRef ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai should my turnstile ref be a template ref too then?
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not contain explicit information about whether your Turnstile ref (for
- Use
<NuxtTurnstile ref="turnstile" />
) should be a template ref using useTemplateRef
or a standard ref
. However, the general pattern in Nuxt UI and related documentation is to use useTemplateRef
for referencing component instances in the template, as it provides better integration and type safety, especially when you want to access exposed methods or properties on the component instance Nuxt UI Form Expose Nuxt UI Stepper Expose.
If your Turnstile component exposes methods (like reset
) that you want to call from your script, using useTemplateRef('turnstile')
is recommended for consistency with Nuxt UI best practices. If you only need a simple reactive value and do not need to access component methods, a standard ref
may suffice.
In summary:- Use
useTemplateRef
for template refs to component instances when you need to access their methods or properties.
- The knowledge sources do not provide a specific example for Turnstile, but this is the recommended pattern for other components in Nuxt UI.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai so when using " form.value?.setErrors([
{ name: "password", message: error.value.message },
]);" to set a custom zod error on a specific field it works but if i click that field and click off it gets revalidated and removed. is that optimal UX or should it remain until the user resubmits the form?
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources explain that when you use
- Field errors are cleared when the user corrects the input or interacts with the field, so users are not blocked by stale errors. - If you want the error to persist until the next form submission, you would need to customize the validation logic or error handling, but this is not the default or recommended behavior in Nuxt UI. In summary:
The default behavior—where the error is cleared on revalidation after user interaction—is considered optimal UX and is how Nuxt UI is designed to work (Custom Validation). This gives immediate feedback and avoids confusing the user with errors that may no longer be relevant. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
setErrors
to set a custom error on a specific field (such as the password field), the error is displayed on that field. However, the Nuxt UI Form component is designed to automatically revalidate fields on certain events (like blur
, input
, or change
), and this can clear the error if the field passes validation after the user interacts with it (Input Events).
This behavior is intentional and aligns with standard UX patterns:- Field errors are cleared when the user corrects the input or interacts with the field, so users are not blocked by stale errors. - If you want the error to persist until the next form submission, you would need to customize the validation logic or error handling, but this is not the default or recommended behavior in Nuxt UI. In summary:
The default behavior—where the error is cleared on revalidation after user interaction—is considered optimal UX and is how Nuxt UI is designed to work (Custom Validation). This gives immediate feedback and avoids confusing the user with errors that may no longer be relevant. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai right but this error that i manually apply comes from my server side validation for example validating a referral code when the user submits the form. but client side the referral field is optional in the zod validation schema. so what happens is the user clicks the referral code field > clicks off > invalid referral code error is gone which doesn't seem ideal as they should resubmit the form again (or clear the error if they make the field empty)
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources confirm that Nuxt UI's form validation system will clear errors on a field when it is revalidated—such as on blur, input, or change events—if the field passes the client-side schema validation (Input Events). Since your referral code field is optional in the Zod schema, any server-side error you set with
- Field errors are cleared on revalidation, even if they were set manually from the server. If you want to change this behavior (e.g., to keep the server error until the user resubmits or clears the field), you would need to implement custom logic, but the knowledge sources do not provide guidance or examples for this pattern. Summary:
- The current behavior (error cleared on blur if field passes client-side validation) is by design in Nuxt UI. - The knowledge sources do not describe a built-in way to persist server-side errors until resubmission or field change. References:
- Nuxt UI Form Input Events - Nuxt UI Form Custom Validation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
setErrors
will be removed as soon as the user interacts with the field and it passes the (non-restrictive) client-side validation.
The documentation does not provide a built-in way to persist server-side errors on a field until the next submission, nor does it discuss best practices for this specific scenario. Therefore, based on the knowledge sources, this is the default and expected behavior in Nuxt UI:- Field errors are cleared on revalidation, even if they were set manually from the server. If you want to change this behavior (e.g., to keep the server error until the user resubmits or clears the field), you would need to implement custom logic, but the knowledge sources do not provide guidance or examples for this pattern. Summary:
- The current behavior (error cleared on blur if field passes client-side validation) is by design in Nuxt UI. - The knowledge sources do not describe a built-in way to persist server-side errors until resubmission or field change. References:
- Nuxt UI Form Input Events - Nuxt UI Form Custom Validation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai for my password field I made a custom component to display the requirements the user should fill in (it's shown whenever there's anything typed in the password input and while not all requirements are met). is there a clean way to ensure that i only get the zod error color on the input field but not the text underneath as ill use my component instead
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not explicitly describe a built-in way in Nuxt UI to apply the error color only to the input field while suppressing the default error/help text below, especially when using a custom password requirements component. However, you can achieve this by controlling the
error
prop on the <UFormField>
and using slots.
- The error
prop on <UFormField>
controls both the error color on the input and the error message below (FormField Error).
- If you set error
to true
(instead of a string), the error color will be applied to the input, but no error message will be shown below. This allows you to display your own custom requirements component underneath the input without the default error text interfering.
Example:
- hasZodError
should be true
if there is a Zod validation error for the password field.
- By passing true
(not a string) to error
, you get the error color on the input but suppress the default error message, letting your custom component handle the requirements display.
This approach is clean and leverages Nuxt UI's documented API for error handling and slot customization (FormField API).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai thanks, and how should i properly deduce whether or not the field has a zod error?
Let me check the knowledge base for you again. One moment! :books:
----------------------
To properly deduce whether a field (such as your password field) has a Zod error in a Nuxt UI form, you should use the form instance’s exposed API. When you reference your form with
For more details, see the Form Expose documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
useTemplateRef('form')
, you gain access to the getErrors(path)
method, which returns an array of errors for a specific field name (Form Expose).
Example:
You can then use hasPasswordError
to control the error
prop on your <UFormField>
:
This approach ensures you are checking for any validation errors (including Zod errors) on the password field in a way that is fully supported and recommended by Nuxt UI’s API.For more details, see the Form Expose documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai "'hasPasswordError' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts-plugin(7022)
const hasPasswordError: any" how should i type it properly? "'form' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts-plugin(7022)
const form: any"
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not provide explicit TypeScript types for the result of
useTemplateRef
or for the computed property that checks for field errors. However, the Nuxt UI documentation shows usage of useTemplateRef
for accessing the form instance and its methods, such as getErrors
, but does not specify the exact types to use for TypeScript (Form Expose).
Given this, you can type your form
ref as any
or use a more specific type if you know the structure, but the documentation does not provide a ready-made type. For the computed property, you can explicitly annotate it as ComputedRef<boolean>
to satisfy TypeScript.
Example:
- form
is typed as any
because the knowledge sources do not provide a more specific type.
- hasPasswordError
is typed as ComputedRef<boolean>
.
If Nuxt UI provides types in the future, you can update these accordingly, but based on the current documentation, this is the most accurate approach available from the knowledge sources.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai so " <UFormField
label="Password"
name="password"
required
:error="hasPasswordError"
>
<UInput
v-model="state.password"
:type="showPassword ? 'text' : 'password'"
icon="i-heroicons-lock-closed"
placeholder="Choose a strong password"
autocomplete="new-password"
:ui="{ trailing: 'pe-1' }"
@input="clearServerError('password')"
>
<template #trailing>
<UButton
color="neutral"
variant="ghost"
:icon="showPassword ? 'i-heroicons-eye-slash-20-solid' : 'i-heroicons-eye-20-solid'"
@click="showPassword = !showPassword"
/>
</template>
</UInput>
<!-- Show my custom password requirements here conditionally and strength indicator -->
</UFormField>' in my form should i put my custom password requirements component inside the formfield or not
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, you should place your custom password requirements component inside the
<UFormField>
as a child, typically below the <UInput>
. This is consistent with how Nuxt UI demonstrates placing additional information, such as help text, hints, or custom content, within a form field (FormField Usage).
By placing your custom component inside <UFormField>
, you ensure it is visually grouped with the password input and benefits from the same layout and accessibility structure. You can conditionally render your requirements component based on your logic (e.g., when the user has started typing or not all requirements are met).
Example:
This approach is in line with Nuxt UI's examples, where additional content (like help or custom components) is placed inside the form field for clarity and accessibility (FormField Help).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai " <UFormField
label="Password"
name="password"
required
:error="hasPasswordError"
>
<UInput
v-model="state.password"
:type="showPassword ? 'text' : 'password'"
icon="i-heroicons-lock-closed"
placeholder="Choose a strong password"
autocomplete="new-password"
:ui="{ trailing: 'pe-1' }"
@input="clearServerError('password')"
>
<template #trailing>
<UButton
color="neutral"
variant="ghost"
:icon="showPassword ? 'i-heroicons-eye-slash-20-solid' : 'i-heroicons-eye-20-solid'"
@click="showPassword = !showPassword"
/>
</template>
</UInput>
<PasswordStrength :password="state.password" />
</UFormField>" how should i go about adding a gap between the input and my strength component
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not mention a built-in prop on
<UFormField>
or <UInput>
specifically for adding spacing between the input and custom content like your <PasswordStrength>
component. However, Nuxt UI examples show that you can use standard utility classes (such as Tailwind CSS classes) to add spacing between elements inside a form field.
A clean approach is to wrap your custom component in a <div>
and apply a margin utility class, such as mt-2
or mt-4
, to create a gap between the input and the strength indicator:
This method is consistent with Nuxt UI documentation, which uses utility classes for spacing in similar scenarios (FormField Help Example).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai "<PasswordStrength v-show="typeof passwordError !== 'string'" :password="state.password" />' is this a clean way to hide my password strength component if password error is a string? as that can be a boolean, string or undefined
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not explicitly discuss using
Yes, using
v-show
or conditional rendering for custom components like <PasswordStrength>
based on the type of an error value. However, they do show that the error
prop on <UFormField>
can accept a string
, boolean
, or undefined
(FormField API), and that you can control the display of custom content inside a form field using standard Vue conditional rendering.
Using v-show="typeof passwordError !== 'string'"
is a reasonable and clean way to hide your password strength component when passwordError
is a string (i.e., when there is a validation error message), since this matches the possible types for the error prop. This approach is consistent with Vue best practices and does not conflict with any Nuxt UI recommendations in the knowledge sources.
Summary:Yes, using
v-show="typeof passwordError !== 'string'"
to conditionally display your <PasswordStrength>
component is a clean and valid approach, given the types supported by the error
prop in Nuxt UI FormField API.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai on my UIinputs inside formfields do i need to apply class="block" to them all? to make them full width
Let me check the knowledge base for you again. One moment! :books:
----------------------
You do not need to apply
class="block"
to all your <UInput>
components inside <UFormField>
to make them full width. Instead, you should use class="w-full"
on the input to ensure it takes the full width of its container, as shown in the Nuxt UI documentation examples:
The documentation consistently uses w-full
for full-width inputs, not block
FormField Usage. If you want your inputs to span the full width, use w-full
rather than block
.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai what about globally applying it to uinputs
Let me check the knowledge base for you again. One moment! :books:
----------------------
The knowledge sources do not explicitly mention a built-in way to globally apply
w-full
(or any class) to all <UInput>
components in Nuxt UI. However, you can globally override the default styles of Nuxt UI components using the app.config.ts
file by customizing the component's theme slots Customize theme Config.
For <UInput>
, you would add the w-full
class to the appropriate slot (usually base
or root
) in your app.config.ts
:
This will apply w-full
to all <UInput>
components by default throughout your application, so you don't have to add it manually each time.
For more details, see the Nuxt UI theme customization documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.