Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosMicrosoft Mechanics: A Copilot Agent Writes the Status Report(23.09.2026 um 03:30 Uhr)
Sichere ProgrammierungOpenTelemetry in the GitHub Copilot app(23.09.2026 um 04:14 Uhr)
Sichere ProgrammierungMy Introduction:(23.09.2026 um 03:53 Uhr)
Sichere ProgrammierungAgentWallex: Content Day (Articles going live)(23.09.2026 um 04:00 Uhr)
Sichere ProgrammierungYour Low-Code Platform Is Fast Until a Customer Builds One Real Table(23.09.2026 um 04:11 Uhr)
YouTube Security VideosMicrosoft Mechanics: A Copilot Agent Writes the Status Report(23.09.2026 um 03:30 Uhr)
Sichere ProgrammierungOpenTelemetry in the GitHub Copilot app(23.09.2026 um 04:14 Uhr)
Sichere ProgrammierungMy Introduction:(23.09.2026 um 03:53 Uhr)
Sichere ProgrammierungAgentWallex: Content Day (Articles going live)(23.09.2026 um 04:00 Uhr)
Sichere ProgrammierungYour Low-Code Platform Is Fast Until a Customer Builds One Real Table(23.09.2026 um 04:11 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Practical Next.js Form Validation with @teonord/validator

Form validation doesn't need to be complicated. In this tutorial, I'll show you how to implement clean, efficient form validation in Next.js using @teonord/validator with a real-world example. Setting Up Our Project First,…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Form validation doesn't need to be complicated. In this tutorial, I'll show you how to implement clean, efficient form validation in Next.js using @teonord/validator with a real-world example.






Setting Up Our Project



First, install the package:




npm install @teonord/validator









Building a Contact Form with Smart Validation



Let's create a contact form that demonstrates the most common validation scenarios you'll encounter in real projects.




// components/ContactForm.tsx
'use client';

import { useState } from 'react';
import { Validator } from '@teonord/validator';

export default function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
phone: '',
subject: '',
message: '',
urgency: 'normal',
agreeToTerms: false
});

const [errors, setErrors] = useState<Record<string, string>>({});

const validationRules = {
name: [{ rule: 'required' }],
email: [
{ rule: 'required' },
{ rule: 'email' }
],
phone: [
{ rule: 'requiredIf', value: ['urgency', 'urgent'] }
],
subject: [
{ rule: 'required' },
{ rule: 'minLength', value: [5] }
],
message: [
{ rule: 'required' },
{ rule: 'minLength', value: [10] },
{ rule: 'maxLength', value: [500] }
],
urgency: [{ rule: 'required' }],
agreeToTerms: [
{ rule: 'accepted' }
]
};

const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();

const validator = new Validator(formData);
const result = validator.validateRules(validationRules);

if (!result.isValid) {
// Convert array errors to simple object
const errorMap: Record<string, string> = {};
Object.keys(result.errors).forEach(key => {
if (result.errors[key].length > 0) {
errorMap[key] = result.errors[key][0];
}
});
setErrors(errorMap);
return;
}

setErrors({});
// Handle form submission
console.log('Form submitted:', formData);
};

const handleChange = (field: string, value: any) => {
setFormData(prev => ({ ...prev, [field]: value }));
// Clear error when user starts typing
if (errors[field]) {
setErrors(prev => {
const newErrors = { ...prev };
delete newErrors[field];
return newErrors;
});
}
};

return (
<div className="max-w-lg mx-auto p-6 bg-white rounded-lg shadow-md">
<h2 className="text-2xl font-bold mb-6">Contact Us</h2>

<form onSubmit={handleSubmit} className="space-y-4">
{/* Name Field */}
<div>
<label className="block text-sm font-medium mb-1">Full Name</label>
<input
type="text"
value={formData.name}
onChange={(e) => handleChange('name', e.target.value)}
className={`w-full p-2 border rounded ${
errors.name ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Enter your full name"
/>
{errors.name && <p className="text-red-500 text-sm mt-1">Name is required</p>}
</div>

{/* Email Field */}
<div>
<label className="block text-sm font-medium mb-1">Email</label>
<input
type="email"
value={formData.email}
onChange={(e) => handleChange('email', e.target.value)}
className={`w-full p-2 border rounded ${
errors.email ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="[email protected]"
/>
{errors.email && (
<p className="text-red-500 text-sm mt-1">
{errors.email.includes('email') ? 'Invalid email format' : 'Email is required'}
</p>
)}
</div>

{/* Phone Field - Conditionally Required */}
<div>
<label className="block text-sm font-medium mb-1">
Phone Number {formData.urgency === 'urgent' && <span className="text-red-500">*</span>}
</label>
<input
type="tel"
value={formData.phone}
onChange={(e) => handleChange('phone', e.target.value)}
className={`w-full p-2 border rounded ${
errors.phone ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="+1 (555) 123-4567"
/>
{errors.phone && <p className="text-red-500 text-sm mt-1">Phone is required for urgent requests</p>}
</div>

{/* Urgency Selection */}
<div>
<label className="block text-sm font-medium mb-1">Urgency</label>
<select
value={formData.urgency}
onChange={(e) => handleChange('urgency', e.target.value)}
className="w-full p-2 border border-gray-300 rounded"
>
<option value="low">Low</option>
<option value="normal">Normal</option>
<option value="urgent">Urgent</option>
</select>
</div>

{/* Subject Field */}
<div>
<label className="block text-sm font-medium mb-1">Subject</label>
<input
type="text"
value={formData.subject}
onChange={(e) => handleChange('subject', e.target.value)}
className={`w-full p-2 border rounded ${
errors.subject ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="What is this regarding?"
/>
{errors.subject && (
<p className="text-red-500 text-sm mt-1">
{errors.subject.includes('minLength') ? 'Subject must be at least 5 characters' : 'Subject is required'}
</p>
)}
</div>

{/* Message Field */}
<div>
<label className="block text-sm font-medium mb-1">Message</label>
<textarea
value={formData.message}
onChange={(e) => handleChange('message', e.target.value)}
rows={4}
className={`w-full p-2 border rounded ${
errors.message ? 'border-red-500' : 'border-gray-300'
}`}
placeholder="Please describe your inquiry..."
/>
{errors.message && (
<p className="text-red-500 text-sm mt-1">
{errors.message.includes('minLength') && 'Message must be at least 10 characters'}
{errors.message.includes('maxLength') && 'Message must be less than 500 characters'}
{errors.message.includes('required') && 'Message is required'}
</p>
)}
<div className="text-sm text-gray-500 text-right">
{formData.message.length}/500
</div>
</div>

{/* Terms Agreement */}
<div className="flex items-center">
<input
type="checkbox"
id="agreeToTerms"
checked={formData.agreeToTerms}
onChange={(e) => handleChange('agreeToTerms', e.target.checked)}
className="mr-2"
/>
<label htmlFor="agreeToTerms" className="text-sm">
I agree to the terms and conditions
</label>
</div>
{errors.agreeToTerms && <p className="text-red-500 text-sm">You must agree to the terms</p>}

{/* Submit Button */}
<button
type="submit"
className="w-full bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600 transition-colors"
>
Send Message
</button>
</form>
</div>
);
}









Server-Side Validation in API Route



For complete security, always validate on the server too:




// app/api/contact/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { Validator } from '@teonord/validator';

export async function POST(request: NextRequest) {
try {
const body = await request.json();

const validationRules = {
name: [{ rule: 'required' }],
email: [{ rule: 'required' }, { rule: 'email' }],
phone: [{ rule: 'requiredIf', value: ['urgency', 'urgent'] }],
subject: [{ rule: 'required' }, { rule: 'minLength', value: [5] }],
message: [{ rule: 'required' }, { rule: 'minLength', value: [10] }],
urgency: [{ rule: 'required' }],
agreeToTerms: [{ rule: 'accepted' }]
};

const validator = new Validator(body);
const result = validator.validateRules(validationRules);

if (!result.isValid) {
return NextResponse.json(
{
success: false,
errors: result.errors
},
{ status: 400 }
);
}

// Process the form data (send email, save to database, etc.)
console.log('Processing contact form:', body);

// Simulate processing delay
await new Promise(resolve => setTimeout(resolve, 1000));

return NextResponse.json({
success: true,
message: 'Thank you for your message! We will get back to you soon.'
});

} catch (error) {
return NextResponse.json(
{ success: false, error: 'Invalid JSON data' },
{ status: 400 }
);
}
}









Key Features Demonstrated






1. Conditional Validation



The phone field is only required when urgency is set to "urgent":




phone: [{ rule: 'requiredIf', value: ['urgency', 'urgent'] }]









2. Multiple Validation Rules



Single fields can have multiple rules:




email: [{ rule: 'required' }, { rule: 'email' }]









3. Length Validation



Control minimum and maximum lengths:




message: [
{ rule: 'required' },
{ rule: 'minLength', value: [10] },
{ rule: 'maxLength', value: [500] }
]









4. Checkbox Validation



Validate boolean values like terms agreement:




agreeToTerms: [{ rule: 'accepted' }]









Real-Time User Experience



The form provides immediate feedback:




  • Clear visual indicators for invalid fields

  • Dynamic error messages that disappear when users start correcting

  • Conditional requirements that change based on user selections

  • Character counting for length-limited fields






Best Practices for Production




  • Consistent Rules: Use the same validation rules on client and server

  • User-Friendly Messages: Provide clear, actionable error messages

  • Progressive Enhancement: Validate as users type, but always validate on submit

  • Security First: Never trust client-side validation alone






Conclusion



This approach gives you:




  • ✅ Clean, readable validation rules

  • ✅ Conditional logic without complex code

  • ✅ Consistent client and server validation

  • ✅ Great user experience with immediate feedback

  • ✅ Type-safe validation with TypeScript



The @teonord/validator package makes form validation straightforward and maintainable, letting you focus on building great features instead of writing complex validation logic.



Ready to implement? Copy the code above and adapt it to your Next.js forms today!



What form validation challenges have you faced in your projects? Share your experiences in the comments!

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Practical Next.js Form Validation with @teonord/validator

Thematisch verwandte Begriffe: Practical, Nextjs, Form, Validation · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-17636 | IBM Financial Transaction Manager (FTM) for RedHat OpenShift could allow…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick