\n \u003C/template>\n\n \u003Ctemplate v-else>\n \u003CDynamicRenderer :config=\"slotContent\" :key=\"slotContent.name || slotName\" />\n \u003C/template>\n \u003C/template>\n \u003C/component>\n\u003C/template>\n```\n\n\n\n#### `index.vue`\n```vue\n\u003Cscript setup lang=\"ts\">\nimport { UButton, UCard, UContainer, UForm, UFormField, UInput } from '#components'\n\nconst config = {\n component: UContainer,\n class: 'h-screen flex justify-center items-center',\n slots: {\n default: [\n {\n component: UCard,\n slots: {\n default: [{\n component: UForm,\n class: 'space-y-4',\n slots: {\n default: [\n {\n component: UFormField,\n label: 'Username',\n name: 'username',\n required: true,\n slots: {\n default: [\n {\n component: UInput,\n placeholder: 'Enter Username',\n value: 'hh'\n }\n ]\n }\n },\n {\n component: UFormField,\n label: 'Password',\n name: 'password',\n required: true,\n slots: {\n default: [\n {\n component: UInput,\n type: 'password',\n placeholder: 'Enter Password',\n value: 'hh'\n }\n ]\n }\n },\n {\n component: UButton,\n label: 'Login',\n icon: 'i-lucide-user',\n variant: 'soft',\n type: 'submit',\n block: true\n }\n ]\n }\n }]\n }\n }\n ]\n }\n}\n\u003C/script>\n\n\u003Ctemplate>\n \u003CDynamicRenderer :config=\"config\" />\n\u003C/template>\n```\n\n### Result \n\n\nIt would also be great if using this approach could eliminate the need to manually import components like:\n\n```ts\nimport { UButton, UCard, UContainer, UForm, UFormField, UInput } from '#components'\n```\n\nand instead rely on automatic resolution by the renderer itself.\n\nThanks for your work on Nuxt UI – it’s a fantastic toolkit!\n\n### Additional context\n\n_No response_",[3039,3042],{"name":3040,"color":3041},"enhancement","a2eeef",{"name":3026,"color":3027},4138,"✨ Feature Request: Add `\u003CDynamicRenderer>` component for config-driven UI rendering","2025-05-12T16:36:30Z","https://github.com/nuxt/ui/issues/4138",0.7093686,{"description":3049,"labels":3050,"number":3054,"owner":3029,"repository":3030,"state":3055,"title":3056,"updated_at":3057,"url":3058,"score":3059},"### Environment\n\n- Operating System: Darwin\n- Node Version: v20.18.3\n- Nuxt Version: 3.16.2\n- CLI Version: 3.24.1\n- Nitro Version: 2.11.9\n- Package Manager: bun@1.1.28\n- Builder: -\n- User Config: devtools, modules, css, future, compatibilityDate\n- Runtime Modules: @nuxt/ui@3.0.2, @nuxt/eslint@1.3.0\n- Build Modules: -\n\n### Is this bug related to Nuxt or Vue?\n\nNuxt\n\n### Version\n\nv3.0.2\n\n### Reproduction\n\nhttps://stackblitz.com/edit/github-s2opq2ko?file=app/pages/index.vue\n\n### Description\n\nGiven this component nesting:\n\n- `UForm`\n - `UModal`\n - `UForm`\n\nThis is rendered as the following html:\n\n- `UForm` -> `form` - ✅\n - `UModal` -> `div` - ✅ (teleported to root)\n - `UForm` -> `div` - ❌ I am expecting `form`.\n\nI couldn't find a mention in the documentation that this is expected behaviour.\n\nTo reproduce:\n1. Run reproduction\n2. Click \"Open modal\" button\n3. Inspect the nested form element. It's a `div`:\n\n\nI am happy to have a crack at a PR, if you're willing to point me in the right direction 😌\n\n\n### Additional context\n\nFor context, this is our use case:\n* User fills out an onboarding form\n* One field in the onboarding form is business details\n* User has option to populate business details via business number (eg. [DUNS](https://www.dnb.com/en-us/smb/duns.html))\n* Business number field open in modal\n* User can enter business number in form in modal\n* User submits form, it populates state in parent form\n\n### Logs\n\n```shell-script\n\n```",[3051,3052,3053],{"name":3020,"color":3021},{"name":3023,"color":3024},{"name":3026,"color":3027},3913,"closed","[Form] Nested `UForm` in `UModal` is not rendered as `form`","2025-04-16T08:34:48Z","https://github.com/nuxt/ui/issues/3913",0.67031133,{"description":3061,"labels":3062,"number":3067,"owner":3029,"repository":3030,"state":3055,"title":3068,"updated_at":3069,"url":3070,"score":3071},"### Description\n\n```\n\u003Cscript setup lang=\"ts\">\nimport * as z from \"zod\";\nimport type { FormSubmitEvent } from \"@nuxt/ui\";\ninterface Props {\n cabinData?: Cabin;\n}\nconst props = defineProps\u003CProps>();\nconst form = useTemplateRef(\"form\");\n\nconst schema = z.object({\n name: z.string().min(1, \"Cabin name is required\"),\n capacity: z.number().min(1, \"Capacity must be at least 1\").optional(),\n price: z.number().min(0, \"Price must be at least 0\").optional(),\n discount: z.number().min(0, \"Discount must be at least 0\").optional(),\n image: z.string().optional(),\n});\n\nconst isDirty: ComputedRef\u003Cboolean | undefined> = computed(() => {\n return form.value?.dirty;\n});\n\ntype Schema = z.output\u003Ctypeof schema>;\nconst state = reactive\u003CPartial\u003CSchema>>({\n name: props.cabinData?.name || \"\",\n capacity: props.cabinData?.capacity || undefined,\n price: props.cabinData?.price || undefined,\n discount: props.cabinData?.discount || undefined,\n image: undefined,\n});\nasync function onSubmit(event: FormSubmitEvent\u003CSchema>) {}\n\u003C/script>\n\n\u003Ctemplate>\n \u003CUForm\n ref=\"form\"\n :schema=\"schema\"\n :state=\"state\"\n class=\"w-full space-y-8\"\n @submit=\"onSubmit\"\n >\n \u003Cdiv class=\"border-b-grey-200 flex gap-12 border-b py-4\">\n \u003Clabel for=\"name\" class=\"w-1/5 font-semibold\">Name\u003C/label>\n \u003CUFormField name=\"name\">\n \u003CUInput\n id=\"name\"\n v-model=\"state.name\"\n color=\"info\"\n :ui=\"{\n base: ' disabled:bg-grey-50/10',\n }\"\n />\n \u003C/UFormField>\n \u003C/div>\n\n \u003Cdiv class=\"border-b-grey-200 flex gap-12 border-b py-4\">\n \u003Clabel for=\"capacity\" class=\"w-1/5 font-semibold\">Capacity\u003C/label>\n \u003CUFormField name=\"capacity\">\n \u003CUInputNumber\n id=\"capacity\"\n v-model=\"state.capacity\"\n color=\"info\"\n :ui=\"{\n base: ' disabled:bg-grey-50/10',\n }\"\n />\n \u003C/UFormField>\n \u003C/div>\n\n \u003Cdiv class=\"border-b-grey-200 flex gap-12 border-b py-4\">\n \u003Clabel for=\"price\" class=\"w-1/5 font-semibold\">Price\u003C/label>\n \u003CUFormField name=\"price\">\n \u003CUInputNumber\n id=\"price\"\n v-model=\"state.price\"\n color=\"info\"\n :ui=\"{\n base: ' disabled:bg-grey-50/10',\n }\"\n />\n \u003C/UFormField>\n \u003C/div>\n\n \u003Cdiv class=\"border-b-grey-200 flex gap-12 border-b py-4\">\n \u003Clabel for=\"discount\" class=\"w-1/5 font-semibold\">Discount\u003C/label>\n \u003CUFormField name=\"discount\">\n \u003CUInputNumber\n id=\"discount\"\n v-model=\"state.discount\"\n color=\"info\"\n :ui=\"{\n base: ' disabled:bg-grey-50/10',\n }\"\n />\n \u003C/UFormField>\n \u003C/div>\n\n \u003Cdiv class=\"flex justify-end pt-4\">\n \u003CUTooltip arrow text=\"Data has not been changed\">\n \u003CUButton\n type=\"submit\"\n class=\"bg-brand-600 text-brand-50 hover:bg-brand-700 px-4 py-2 uppercase hover:cursor-pointer\"\n size=\"lg\"\n :disabled=\"!isDirty\"\n >\n Update Data\n \u003C/UButton>\n \u003C/UTooltip>\n\n \u003CUButton\n class=\"bg-grey-200 text-grey-900 hover:bg-grey-50 ml-2 px-4 py-2 uppercase hover:cursor-pointer\"\n size=\"lg\"\n @click=\"\n state.name = '';\n state.capacity = undefined;\n state.price = undefined;\n state.discount = undefined;\n state.image = undefined;\n form?.clear();\n \"\n >\n Cancel\n \u003C/UButton>\n \u003C/div>\n \u003C/UForm>\n\u003C/template>\n\n```\n\n> this is my code i want disable button depending on if fields is dirty or not i'm using computed now but i used ref alswo watchEffect and watch with getter to watch if is there any changes in fields,but depending on documentation dirty is ref boolean but it doesn't change what am i doing wrong ?",[3063,3066],{"name":3064,"color":3065},"question","d876e3",{"name":3023,"color":3024},4402,"UForm dirty isn't reactive ?","2025-06-26T13:33:41Z","https://github.com/nuxt/ui/issues/4402",0.6895162,{"description":3073,"labels":3074,"number":3079,"owner":3029,"repository":3030,"state":3055,"title":3080,"updated_at":3081,"url":3082,"score":3083},"### For what version of Nuxt UI are you asking this question?\n\nv2.x\n\n### Description\n\nI'm using the FormGroup component, and I've set the error to true, however unless it contains a non-empty text value the error slot won't render. Is this intentional or a bug? I would tend to think it's the latter.\n\n```\n\u003CUFormGroup :error=\"true\">\n \u003Ctemplate #error>\n \u003Cdiv>I will not render\u003C/div>\n \u003Ctemplate>\n\u003C/UFormGroup>\n```\n\n```\n\u003CUFormGroup :error=\"true && 'some error'\">\n \u003Ctemplate #error>\n \u003Cdiv>I will render\u003C/div>\n \u003Ctemplate>\n\u003C/UFormGroup>\n```",[3075,3076],{"name":3020,"color":3021},{"name":3077,"color":3078},"stale","ededed",2634,"FormGroup error with error slot","2025-06-14T15:36:58Z","https://github.com/nuxt/ui/issues/2634",0.69216967,{"description":3085,"labels":3086,"number":3088,"owner":3029,"repository":3030,"state":3055,"title":3089,"updated_at":3090,"url":3091,"score":3092},"### For what version of Nuxt UI are you suggesting this?\n\nv2.x\n\n### Description\n\nIt would be cool if the errors array from UForm supported the message parameter having an array value (multiple messages). The default backwards compatible method could just join them with a space or something. (See https://ui.nuxt.com/components/form-group#props)\nThat is all.\n\n### Additional context\n\n_No response_",[3087],{"name":3040,"color":3041},2389,"Nested form validation array of messages","2025-06-29T17:10:53Z","https://github.com/nuxt/ui/issues/2389",0.7005721,{"description":3094,"labels":3095,"number":3107,"owner":3029,"repository":3030,"state":3055,"title":3108,"updated_at":3109,"url":3110,"score":3111},"### Environment\n\n- Operating System - Ubuntu 22\n- Node Version: 22\n- Nuxt Version: 3.17.5\n- CLI Version: 3.25.1\n- Package Manager: pnpm@10.9.0\n\n### Is this bug related to Nuxt or Vue?\n\nNuxt\n\n### Version\n\n3.17.5\n\n### Reproduction\n\n```javascript\nconst fields = ref([\n {\n name: 'code',\n type: 'otp',\n placeholder: 'Enter 6-digit code',\n otp: {\n length: 6,\n placeholder: '●',\n },\n },\n])\n\nconst submitButtonOptions = computed(() => ({\n label: 'Verify Code',\n loading: loading.value,\n}))\n\u003C/script>\n\n\u003Ctemplate>\n \u003Cdiv class=\"flex min-h-screen items-center justify-center p-4\">\n \u003CUPageCard class=\"w-full max-w-md\">\n \u003CUAuthForm\n :schema=\"schema\"\n :state=\"credentials\"\n :fields=\"fields\"\n :loading=\"loading\"\n title=\"Multi-Factor Authentication\"\n subtitle=\"Enter the 6-digit code from your authenticator app to continue.\"\n :submit=\"submitButtonOptions\"\n @submit=\"verifyMFA\"\n >\n \u003Ctemplate #header>\n \u003CNuxtImg\n src=\"/thinkrocket-logo.png\"\n alt=\"ThinkRocket Logo\"\n width=\"100\"\n class=\"mx-auto\"\n preset=\"contain\"\n />\n \u003C/template>\n\n \u003Ctemplate #validation>\n \u003CUAlert\n v-if=\"mfaError\"\n color=\"error\"\n icon=\"i-lucide-alert-circle\"\n :title=\"mfaError\"\n class=\"mb-4\"\n />\n \u003C/template>\n\n \u003Ctemplate #footer>\n \u003Cdiv class=\"text-center space-y-2\">\n \u003Cp class=\"text-sm text-gray-600 dark:text-gray-300\">\n Check your authenticator app for the current code.\n \u003C/p>\n \u003CUButton variant=\"ghost\" size=\"sm\" :loading=\"loading\" @click=\"refreshChallenge\">\n \u003CUIcon name=\"i-lucide-refresh-cw\" class=\"h-4 w-4 mr-1\" />\n Get New Code\n \u003C/UButton>\n \u003C/div>\n \u003C/template>\n \u003C/UAuthForm>\n \u003C/UPageCard>\n \u003C/div>\n\u003C/template>\n```\n\n### Description\n\n`:fields` is throwing typescript error. Only an issue with `otp`. Looking in\n\n- `node_modules/.pnpm/@nuxt+ui-pro@3.1.3_@babel+parser@7.27.5_db0@0.3.2_better-sqlite3@11.10.0__embla-carouse_48b559106e80aa1b3007fc5d3af2ab7f/node_modules/@nuxt/ui-pro/dist/runtime/components/AuthForm.vue.d.ts`\n- `node_modules/.pnpm/@nuxt+ui@3.1.3_@babel+parser@7.27.5_db0@0.3.2_better-sqlite3@11.10.0__embla-carousel@8._6f36fdd0332a5dab432a961d27814af8/node_modules/@nuxt/ui/dist/runtime/components/PinInput.vue.d.ts`\n- `node_modules/.pnpm/reka-ui@2.3.1_typescript@5.8.3_vue@3.5.16_typescript@5.8.3_/node_modules/reka-ui/dist/index.d.ts`\n \nI'm not seeing what I'm missing. The [docs](https://ui.nuxt.com/components/auth-form#props) don't give any other details than the example.\n\n```\nVue: Type\n{\n name: string;\n type: string;\n placeholder: string;\n otp: {\n length: number;\n placeholder: string;\n };\n}[]\nis not assignable to type AuthFormField[]\nType\n{\n name: string;\n type: string;\n placeholder: string;\n otp: {\n length: number;\n placeholder: string;\n };\n}\nis not assignable to type AuthFormField\n```\n\n### Additional context\n\n_No response_\n\n### Logs\n\n```shell-script\n\n```",[3096,3097,3100,3101,3104,3105],{"name":3020,"color":3021},{"name":3098,"color":3099},"needs reproduction","CB47CF",{"name":3023,"color":3024},{"name":3102,"color":3103},"nuxt/ui-pro","00dc82",{"name":3026,"color":3027},{"name":3106,"color":3078},"closed-by-bot",4317,"UAuthForm otp typescript error","2025-06-18T02:14:57Z","https://github.com/nuxt/ui/issues/4317",0.70790786,{"description":3113,"labels":3114,"number":3118,"owner":3029,"repository":3030,"state":3055,"title":3119,"updated_at":3120,"url":3121,"score":3122},"### Environment\n\nOperating System: mac os\nNode Version: v22.14.0\nLaravel Version: 12.12.0\nNitro Version: -\nPackage Manager: bun 1.2.11\nBuilder: -\nUser Config: -\nRuntime Modules: -\nBuild Modules: -\n\n### Is this bug related to Nuxt or Vue?\n\nVue\n\n### Version\n\nv3.1.1\n\n### Reproduction\n\nN/A\n\n### Description\n\nI'm using the example from the documentation for implementing a login and the button behaves like a link. I've already tried as=\"button\" and it doesn't work.\n\n```\n\u003Cscript setup lang=\"ts\">\nimport * as z from 'zod'\nimport type { FormSubmitEvent } from '@nuxt/ui'\n\nconst schema = z.object({\n email: z.string().email('Invalid email'),\n password: z.string().min(8, 'Must be at least 8 characters')\n})\n\ntype Schema = z.output\u003Ctypeof schema>\n\nconst state = reactive\u003CPartial\u003CSchema>>({\n email: undefined,\n password: undefined\n})\n\nconst toast = useToast()\nasync function onSubmit(event: FormSubmitEvent\u003CSchema>) {\n toast.add({ title: 'Success', description: 'The form has been submitted.', color: 'success' })\n console.log(event.data)\n}\n\u003C/script>\n\u003Ctemplate>\n \u003CUForm :schema=\"schema\" :state=\"state\" class=\"space-y-4\" @submit=\"onSubmit\">\n \u003CUFormField label=\"Email\" name=\"email\">\n \u003CUInput v-model=\"state.email\" />\n \u003C/UFormField>\n \u003CUFormField label=\"Password\" name=\"password\">\n \u003CUInput v-model=\"state.password\" type=\"password\" />\n \u003C/UFormField>\n \u003CUButton type=\"submit\">\n Submit\n \u003C/UButton>\n \u003C/UForm>\n\u003C/template>\n```\n\n### Additional context\n\n\n\n### Logs\n\n```shell-script\n\n```",[3115,3116,3117],{"name":3020,"color":3021},{"name":3023,"color":3024},{"name":3026,"color":3027},4095,"UButton works as a link in Inertia","2025-05-07T08:12:17Z","https://github.com/nuxt/ui/issues/4095",0.7152626,{"description":3124,"labels":3125,"number":3128,"owner":3029,"repository":3030,"state":3055,"title":3129,"updated_at":3130,"url":3131,"score":3132},"### For what version of Nuxt UI are you suggesting this?\n\nv2.x\n\n### Description\n\nIt would be great if there was an option for eager validation if there are errors present on the group.\n\nFor example, when initially filling out the field you don't want eager validation as it's distracting when you aren't finished typing.\n\nHowever if you tab away and there's an error, when fixing the error you'd want immediate feedback with eager-validation.\n\nSo I propose a new prop: `eager-validation-on-error=\"true\"` to improve the UX of forms.\n\nThanks!\n\n### Additional context\n\n_No response_",[3126,3127],{"name":3040,"color":3041},{"name":3023,"color":3024},2599,"FormGroup eager-validation when errors exist","2025-06-29T17:15:23Z","https://github.com/nuxt/ui/issues/2599",0.7181919,{"description":3134,"labels":3135,"number":3139,"owner":3029,"repository":3030,"state":3055,"title":3140,"updated_at":3141,"url":3142,"score":3143},"### For what version of Nuxt UI are you asking this question?\n\nv2.x\n\n### Description\n\nHow can i use [Zod](https://zod.dev/) to validate an [UInput file field](https://ui.nuxt.com/components/input#type)? \n\nLet's say you have the following code:\n(I found the example over [here](https://blog.stackademic.com/upgrade-your-full-stack-form-validation-with-zod-and-react-hook-form-in-next-js-107b014628a3).)\n\n```vue\n\u003CUForm :schema=\"schema\" :state=\"state\" @submit=\"onSubmit\">\n\n \u003CUFormGroup name=\"picture\" label=\"Picture\">\n \u003CUInput v-model=\"state.picture\" type=\"file\" @change=\"onChangeFile\"/>\n \u003C/UFormGroup>\n\n \u003CUButton type=\"submit\">\n Submit\n \u003C/UButton>\n\n\u003C/UForm>\n```\n\n```ts\n\u003Cscript setup lang=\"ts\">\n import { z } from 'zod';\n\n const state = reactive({\n picture: undefined,\n })\n\n const schema = z.object({\n picture: z.custom\u003CFileList>()\n .transform((val) => {\n if (val instanceof File) return val;\n if (val instanceof FileList) return val[0];\n return null;\n })\n .superRefine((file, ctx) => {\n if (!(file instanceof File)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n fatal: true,\n message: 'Not a file',\n });\n return z.NEVER;\n }\n if (file.size > 5 * 1024 * 1024) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'Max file size allowed is 5MB',\n });\n }\n if (\n !['image/jpeg', 'image/png', 'image/webp', 'image/jpg'].includes(\n file.type\n )\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'File must be an image (jpeg, jpg, png, webp)',\n });\n }\n })\n });\n\n type Schema = z.infer\u003Ctypeof schema>;\n\n async function onSubmit (event: FormSubmitEvent\u003CSchema>) {\n console.log(event.data);\n }\n\u003C/script>\n```\n\nAs aspected the following onChange function logs a FileList\n\n```ts\nfunction onChangeFile(event: Event) {\n console.log(event)\n}\n```\n\nBut when I log val in the transform function of Zod\n\n```ts\n.transform((val) => {\n console.log(val);\n if (val instanceof File) return val;\n if (val instanceof FileList) return val[0];\n return null;\n})\n```\n\nI get a string like this:\n\n```\nC:\\fakepath\\Screenshot 2024-10-25 at 10.26.36.png\n```\n\nCan someone please help me out, i'm looking for a few days now for a solution.",[3136,3137,3138],{"name":3064,"color":3065},{"name":3106,"color":3078},{"name":3077,"color":3078},2462,"UInput with type='file', how to validate with Zod?","2025-06-18T09:05:55Z","https://github.com/nuxt/ui/issues/2462",0.72003144,["Reactive",3145],{},["Set"],["ShallowReactive",3148],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$fQaAydQH2uNNTjdD2wlpXyCR8Oas9NfjfmKrrmaTg6is":-1},"/nuxt/ui/2674"]