[{"data":1,"prerenderedAt":369},["ShallowReactive",2],{"blog-prompts/validate-client-input":3},{"id":4,"title":5,"body":6,"category":348,"date":349,"dateModified":350,"description":351,"draft":352,"extension":353,"faq":354,"featured":352,"headerVariant":355,"image":354,"keywords":354,"meta":356,"navigation":357,"ogDescription":358,"ogTitle":354,"path":359,"readTime":354,"schemaOrg":360,"schemaType":361,"seo":362,"sitemap":363,"stem":364,"tags":365,"twitterCard":367,"__hash__":368},"blog/blog/prompts/validate-client-input.md","Validate Client Input with AI Prompts",{"type":7,"value":8,"toc":339},"minimark",[9,16,21,24,72,76,79,117,127,131,134,200,204,207,260,269,285,289,292,313,327],[10,11,12],"tldr",{},[13,14,15],"p",{},"Client-side validation improves UX by giving instant feedback, but it's NOT security. Use it for user experience, but always duplicate validation server-side. These prompts help you build accessible, helpful form validation with libraries like Zod, React Hook Form, or native HTML5.",[17,18,20],"h2",{"id":19},"react-hook-form-zod","React Hook Form + Zod",[13,22,23],{},"Use this prompt to set up form validation with React Hook Form and Zod. Your AI will generate a complete signup form component with a typed schema, real-time validation on blur, error messages, and loading state handling.",[25,26,28,31,34,50,53,56],"prompt-box",{"title":27},"Form Validation Setup",[13,29,30],{},"Set up form validation with React Hook Form and Zod.",[13,32,33],{},"Install:\nnpm install react-hook-form @hookform/resolvers zod",[13,35,36,37,41,42,45,46,49],{},"Create schema:\nconst signupSchema = z.object({\nemail: z.string().email('Please enter a valid email'),\npassword: z.string()\n.min(8, 'Password must be at least 8 characters')\n.regex(/",[38,39,40],"span",{},"A-Z","/, 'Password must contain uppercase letter')\n.regex(/",[38,43,44],{},"0-9","/, 'Password must contain a number'),\nconfirmPassword: z.string()\n}).refine(data => data.password === data.confirmPassword, {\nmessage: \"Passwords don't match\",\npath: ",[38,47,48],{},"'confirmPassword'","\n});",[13,51,52],{},"Use in component:\nconst { register, handleSubmit, formState: { errors } } = useForm({\nresolver: zodResolver(signupSchema)\n});",[13,54,55],{},"Show me the complete component with:",[57,58,59,63,66,69],"ul",{},[60,61,62],"li",{},"Real-time validation on blur",[60,64,65],{},"Error messages under each field",[60,67,68],{},"Disabled submit until valid",[60,70,71],{},"Loading state during submission",[17,73,75],{"id":74},"html5-native-validation","HTML5 Native Validation",[13,77,78],{},"Copy this prompt to enhance your forms with HTML5 native validation attributes. Your AI will add required, pattern, minlength, and type constraints to your markup along with custom JavaScript validation and CSS styling for invalid fields.",[25,80,82,85,88,108,111,114],{"title":81},"Native Form Validation",[13,83,84],{},"Improve my forms with HTML5 native validation.",[13,86,87],{},"Native attributes:",[57,89,90,93,96,99,102,105],{},[60,91,92],{},"required: Field must have value",[60,94,95],{},"type=\"email\": Must be valid email format",[60,97,98],{},"type=\"url\": Must be valid URL",[60,100,101],{},"minlength/maxlength: Character limits",[60,103,104],{},"min/max: Number range",[60,106,107],{},"pattern: Custom regex",[13,109,110],{},"Example:",[13,112,113],{},"Custom validation with JavaScript:\ninput.setCustomValidity('Custom error message');\ninput.reportValidity();",[13,115,116],{},"Style invalid fields:\ninput:invalid { border-color: red; }",[118,119,120],"warning-box",{},[13,121,122,126],{},[123,124,125],"strong",{},"Client validation is for UX only:"," Never rely on it for security. Attackers can disable JavaScript, modify requests, or call your API directly. Server-side validation is mandatory.",[17,128,130],{"id":129},"accessible-error-messages","Accessible Error Messages",[13,132,133],{},"This prompt asks your AI to make your form validation fully accessible. You'll get ARIA attributes, focus management on submit errors, screen reader announcements, and error messages that don't rely on color alone.",[25,135,137,140,143,161,163,166,169,180,183,186],{"title":136},"Accessible Validation UX",[13,138,139],{},"Make my form validation accessible to all users.",[13,141,142],{},"Accessibility requirements:",[144,145,146,149,152,155,158],"ol",{},[60,147,148],{},"Error messages linked with aria-describedby",[60,150,151],{},"aria-invalid=\"true\" on invalid fields",[60,153,154],{},"Focus management - focus first error on submit",[60,156,157],{},"Screen reader announcements for errors",[60,159,160],{},"Don't rely on color alone (use icons/text too)",[13,162,110],{},[13,164,165],{},"Email",[13,167,168],{},"{errors.email && (",[170,171,176],"pre",{"className":172,"code":174,"language":175},[173],"language-text","   {errors.email.message}\n","text",[177,178,174],"code",{"__ignoreMap":179},"",[13,181,182],{},")}",[13,184,185],{},"On form submit with errors:",[144,187,188,191,194,197],{},[60,189,190],{},"Prevent submission",[60,192,193],{},"Show error summary at top",[60,195,196],{},"Focus the error summary or first invalid field",[60,198,199],{},"Announce \"Form has X errors\" to screen readers",[17,201,203],{"id":202},"real-time-validation-patterns","Real-Time Validation Patterns",[13,205,206],{},"Use this prompt to implement user-friendly validation timing that avoids annoying users. Your AI will generate validate-on-blur logic, touched-field tracking, debounced async validation, and conditional error display.",[25,208,210,213,216,230,241,248,251,257],{"title":209},"Validation Timing",[13,211,212],{},"Implement user-friendly validation timing.",[13,214,215],{},"Best practices:",[144,217,218,221,224,227],{},[60,219,220],{},"Don't validate on every keystroke (annoying)",[60,222,223],{},"Validate on blur (leaving field)",[60,225,226],{},"Re-validate on change after first error shown",[60,228,229],{},"Validate all on submit attempt",[13,231,232,233,236,237,240],{},"Implementation:\nconst ",[38,234,235],{},"touched, setTouched"," = useState({});\nconst ",[38,238,239],{},"errors, setErrors"," = useState({});",[13,242,243,244,247],{},"// Validate on blur\nconst handleBlur = (field) => {\nsetTouched({ ...touched, ",[38,245,246],{},"field",": true });\nvalidateField(field);\n};",[13,249,250],{},"// Only show error if field touched\n{touched.email && errors.email && (\n{errors.email}\n)}",[13,252,253,254,256],{},"Debounce for expensive validations:\nconst debouncedValidate = useMemo(\n() => debounce(validateUsername, 300),\n",[38,255],{},"\n);",[13,258,259],{},"// Check username availability after typing stops\ndebouncedValidate(e.target.value)} />",[261,262,263],"tip-box",{},[13,264,265,268],{},[123,266,267],{},"Pro tip:"," Share validation schemas between frontend and backend. With Zod, you can define once and use in both React Hook Form and your API routes, ensuring consistency.",[270,271,272,279],"faq-section",{},[273,274,276],"faq-item",{"question":275},"Should I disable the submit button until form is valid?",[13,277,278],{},"It's a UX preference. Disabled buttons can confuse users who don't see errors. An alternative is to allow submission, then show all errors at once with focus on the first error.",[273,280,282],{"question":281},"How do I validate async (like checking if username exists)?",[13,283,284],{},"Use debounced validation on change/blur. Show a loading spinner while checking. Cache results to avoid repeated API calls for the same value.",[17,286,288],{"id":287},"further-reading","Further Reading",[13,290,291],{},"Want to understand the vulnerability before fixing it? These guides explain what's happening and why.",[57,293,294,301,307],{},[60,295,296],{},[297,298,300],"a",{"href":299},"/blog/how-to/validate-user-input","Input validation guide",[60,302,303],{},[297,304,306],{"href":305},"/blog/vulnerabilities/sql-injection","SQL injection prevention",[60,308,309],{},[297,310,312],{"href":311},"/blog/vulnerabilities/exposed-api-keys","Understanding exposed API keys",[314,315,316,322],"related-articles",{},[317,318],"related-card",{"description":319,"href":320,"title":321},"Server-side validation","/blog/prompts/sanitize-user-input","Sanitize User Input",[317,323],{"description":324,"href":325,"title":326},"Complete form security","/blog/prompts/secure-forms","Secure Forms",[328,329,332,336],"cta-box",{"href":330,"label":331},"/","Start Free Scan",[17,333,335],{"id":334},"audit-your-forms","Audit Your Forms",[13,337,338],{},"Scan your forms for validation and security gaps.",{"title":179,"searchDepth":340,"depth":340,"links":341},2,[342,343,344,345,346,347],{"id":19,"depth":340,"text":20},{"id":74,"depth":340,"text":75},{"id":129,"depth":340,"text":130},{"id":202,"depth":340,"text":203},{"id":287,"depth":340,"text":288},{"id":334,"depth":340,"text":335},"prompts","2026-02-27","2026-03-06","AI prompts to implement client-side input validation. Create real-time form feedback with proper validation patterns for better UX and security.",false,"md",null,"cyan",{},true,"AI prompts to implement client-side validation for forms.","/blog/prompts/validate-client-input","[object Object]","BlogPosting",{"title":5,"description":351},{"loc":359},"blog/prompts/validate-client-input",[366],"Frontend","summary_large_image","dkFYQctMceqaihC1wvg2HZKn3ML4iVXFlt4lNhwquBM",1775843937979]