The Fear That Paralyzed Me
For months, I had one nagging worry: What if my contact form gets flooded with submissions and I rack up a massive Resend bill?
I'd lie awake thinking about it. Thousands of form submissions. Email after email firing off into the void. My bank account slowly draining as I paid for each perfectly crafted notification.
So naturally, I did what any reasonable developer would do: I procrastinated building the form entirely.
The Reality Check
Here's what I actually built when I finally sat down to "quickly throw together" a contact form:
The Frontend Masterpiece
// Just a "simple" form with Zod validation
const FormSchema = z.object({
name: z.string().optional(),
email: z.string().min(1).email("Please enter a valid email address."),
subject: z.string().min(1, "Please select a subject category."),
content: z.string().min(10).max(500),
consent: z.boolean().refine((val) => val === true, {
message: "You must agree to allow us to contact you.",
}),
});
Complete with:
- React Hook Form integration for seamless UX
- Dynamic error states that change border colors
- Character counters for the message field
- Subject categorization with descriptions
- Consent checkboxes for GDPR compliance
- Loading states with spinner animations
- Confetti celebrations on successful submission
The Backend Fortress
My "simple" API route became a 180-line monument to defensive programming:
export async function POST(request: Request) {
// Validate required fields
if (!email || !content || !subject || !consent) {
return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
}
// Validate environment variables
if (!process.env.RESEND_API_KEY || !process.env.FROM_EMAIL || !process.env.TO_EMAIL) {
console.error('Email service not configured');
return NextResponse.json({ error: "Email service not configured" }, { status: 500 });
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(process.env.TO_EMAIL)) {
console.error('TO_EMAIL has invalid format');
return NextResponse.json({ error: "Email service configuration invalid" }, { status: 500 });
}
// ... 150 more lines of bulletproof error handling
}
The Email Template Empire
And then came the pièce de résistance: beautifully crafted HTML email templates.
Not one, but TWO templates:
- Thank you email for the user (with gradient headers and responsive design)
- Notification email for me (with quick-action buttons and structured data)
<div class="header">
<h1 style="margin: 0; font-size: 28px; font-weight: 600;">Thank You!</h1>
<p style="margin: 10px 0 0 0; opacity: 0.9;">Your message has been received</p>
</div>
<div class="highlight-box">
<h3>Message Summary:</h3>
<p><strong>Category:</strong> <span class="subject-badge">${subjectLabel}</span></p>
<p><strong>Your message:</strong></p>
<p style="font-style: italic;">"${data.content}"</p>
</div>
Complete with:
- Responsive CSS for mobile devices
- Brand-consistent styling with gradients
- Professional typography using system fonts
- Structured data for easy scanning
- Quick-reply buttons for efficiency
The Punchline
After weeks of architecture planning, validation schemas, error boundaries, and pixel-perfect email templates...
My contact form gets approximately 3 submissions per month.
Three.
Not three thousand. Not three hundred. Three.
My Resend bill? A whopping $0.00. They have a generous free tier that I'll never exceed unless I somehow become the next Ryan Dahl.
The Developer's Dilemma
This is peak developer behavior: solving problems that don't exist while avoiding the simple solution that actually works.
I spent more mental energy worrying about scaling issues than I did building the actual feature. Classic over-engineering disguised as "being prepared."
The questions I should have asked:
- Do I even need a contact form?
- Will anyone actually use it?
- Can I start simple and add features later?
The questions I actually asked:
- What if I get 10,000 submissions in one day?
- How do I handle email bounces?
- Should I implement rate limiting?
- What about GDPR compliance?
- Do I need a Redis cache for form submissions?
The Lesson (That I'll Probably Ignore Next Time)
Sometimes the biggest barrier to shipping is our own imagination.
I created elaborate solutions for edge cases that haven't happened, may never happen, and would be easy to fix if they actually did happen.
The real paradox: I built a robust, production-ready contact form while being terrified of the production traffic it would never receive.
What I'd Do Differently
Start with a mailto:
link.
Seriously.
A simple mailto:contact@example.com
would have solved 99% of the problem with 0% of the complexity.
Once I actually got enough contact requests to justify the engineering effort, then build the fancy form.
But let's be honest — I probably would have over-engineered it anyway. It's what we do.
Currently accepting contact form submissions at a very sustainable rate of 3 per month. Email infrastructure costs: $0. Hours spent worrying about email costs: Immeasurable.