اعتبارسنجی فرم در Next.js با Zod: از کلاینت تا سرور
نویسنده: آرش لطیفی
آموزش عملی اعتبارسنجی فرم با Zod و React Hook Form در Next.js؛ یک اسکیمای مشترک برای کلاینت و Server Actions، مدیریت خطا و تجربه کاربری تمیز.
خلاصه: یک اسکیمای
Zodرا منبع حقیقت قرار دهید و هم در کلاینت باReact Hook Formو هم درServer Actionsاستفاده کنید. نتیجه اعتبارسنجی سریع، پیام خطای یکسان و امنیت سمت سرور بدون تکرار کد است.
چرا Zod برای فرمهای Next.js
اعتبارسنجی فقط در کلاینت کافی نیست و فقط در سرور تجربه کاربری را کند میکند. راه حل منبع واحد است: اسکیمای Zod که هم تایپ میدهد و هم در هر دو سمت اجرا میشود. این الگو با Server Actions و useActionState تمیز جفت میشود و از ناهماهنگی پیام خطا جلوگیری میکند.
اگر روی مرز کلاینت و سرور حساس هستید، مرور مرز use-client و آلودگی RSC و کش و PPR در Next.js 15 کمک میکند تا منطق اعتبارسنجی را در جای درست قرار دهید.
اسکیمای مشترک؛ منبع حقیقت
یک فایل schemas/contact.ts بسازید و فقط همان را همه جا وارد کنید. پیامها را فارسی و کوتاه بنویسید و طول ورودیها را محدود کنید تا از اسپم و ورودیهای غولپیکر جلوگیری شود.
این اسکیما هم تایپ خروجی میدهد و هم با zodResolver و هم در سرور کار میکند. تغییر قانون فقط در یک جا انجام میشود.
کلاینت: React Hook Form + zodResolver
برای تجربه سریع، اعتبارسنجی را در کلاینت با React Hook Form اجرا کنید اما پیام خطا را از همان اسکیما بگیرید.
نکتهها: از mode: "onBlur" برای کاهش نویز استفاده کنید، aria-invalid را ست کنید و دکمه را هنگام isSubmitting غیرفعال کنید.
سرور: اعتبارسنجی مطمئن با Server Actions
هرگز به کلاینت اعتماد نکنید. همان اسکیما را در Server Action دوباره اجرا کنید و خطاها را به فرم برگردانید.
این الگو با بهینهسازی RTL در Next.js 15 هم سازگار است چون پیامهای خطا فارسی و جهت نوشتار درست میماند.
مقایسه ابزارها
انتخاب ابزار به نیاز پروژه بستگی دارد اما برای اکثر فرمهای Next.js ترکیب Zod و React Hook Form کمهزینهترین است.
| ابزار | نقاط قوت | مناسب برای | نکته |
| --- | --- | --- | --- |
| Zod + React Hook Form | تایپ قوی، اسکیمای مشترک کلاینت/سرور، اکوسیستم بزرگ | فرمهای معمول تا پیچیده | zodResolver را فراموش نکنید |
| Valibot | حجم کمتر، سرعت بیشتر | پروژههای حساس به باندل | API متفاوت از Zod |
| Yup | سابقه طولانی | مهاجرت از کد قدیمی | تایپ ضعیفتر از Zod |
اگر باندل برایتان حیاتی است، Valibot را تست کنید ولی مستندات و مثالهای Zod در اکوسیستم Next.js بیشتر است.
چکلیست پیادهسازی تمیز
- [ ] اسکیما در یک فایل مشترک تعریف شد و در کلاینت و سرور وارد شد
- [ ] پیامهای خطا کوتاه، فارسی و یکسان در هر دو سمت هستند
- [ ] ورودیها
maxدارند وtrimیاtransformبرای فضاهای اضافی اعمال شد - [ ]
aria-invalidوaria-describedbyبرای دسترسیپذیری ست شد - [ ] دکمه ارسال هنگام
isSubmittingوpendingغیرفعال میشود - [ ] اعتبارسنجی سرور با
safeParseو برگرداندنfieldErrorsانجام شد - [ ] تست دستی با ورودی خالی، ایمیل نامعتبر و پیام خیلی بلند انجام شد
- [ ] لاگ سرور برای خطاهای اعتبارسنجی بدون نشت داده حساس فعال شد
FAQ
آیا فقط اعتبارسنجی کلاینت کافی نیست؟ خیر. کلاینت قابل دور زدن است. همیشه همان اسکیما را در سرور هم اجرا کنید تا امنیت و یکپارچگی داده تضمین شود.
Zod را کجا نگه دارم تا تکرار نشود؟
در schemas/ کنار app و فقط از همان یک خروجی contactSchema در فرم، API Route و Server Action استفاده کنید.
چطور فایل آپلود را هم اعتبارسنجی کنم؟
از z.instanceof(File).refine(f => f.size < 2_000_000, "حجم فایل زیاد است") استفاده کنید و نوع فایل را با refine روی type چک کنید؛ اعتبارسنجی نهایی حجم و نوع را دوباره در سرور تکرار کنید.