Flow Form
A theme-aware animated contact form with progress tracking, validation, and micro-interactions.
Installation
Backend Setup
The form expects an API endpoint at /api/send that accepts a POST request with JSON.
Example: Next.js Route Handler for Nodemailer:
1EMAIL_HOST=smtp.example.com2EMAIL_PORT=5873EMAIL_USER=your_email@example.com4EMAIL_PASS=your_email_password5EMAIL_TO=recipient@example.com
1import { NextResponse } from "next/server";2import nodemailer from "nodemailer";3 4export async function POST(request: Request) {5 try {6 const { name, email, subject, message } = await request.json();7 8 if (!name || !email || !subject || !message) {9 return NextResponse.json(10 { error: "All fields are required" },11 { status: 400 },12 );13 }14 15 // Simple email validation16 if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {17 return NextResponse.json(18 { error: "Invalid email address" },19 { status: 400 },20 );21 }22 23 const transporter = nodemailer.createTransport({24 host: process.env.EMAIL_HOST,25 port: Number(process.env.EMAIL_PORT),26 secure: Number(process.env.EMAIL_PORT) === 465,27 auth: {28 user: process.env.EMAIL_USER,29 pass: process.env.EMAIL_PASS,30 },31 });32 33 await transporter.sendMail({34 from: `"${name}" <${email}>`,35 to: process.env.EMAIL_TO,36 subject: `[FlowForm] ${subject}`,37 text: message,38 html: `<p>${message}</p><p>From: ${name} (${email})</p>`,39 });40 41 return NextResponse.json({42 success: true,43 message: "Message sent successfully!",44 });45 } catch (error) {46 console.error("FlowForm error:", error);47 return NextResponse.json({ error: "Server error" }, { status: 500 });48 }49}
Props
Usage
1"use client";2 3import FlowForm from "@/components/ui/flow-form";4 5export default function Page() {6 const handleSubmit = async (data: Record<string, string>) => {7 const response = await fetch("/api/send", {8 method: "POST",9 headers: { "Content-Type": "application/json" },10 body: JSON.stringify(data),11 });12 return response.json();13 };14 15 return (16 <div className="flex min-h-screen items-center justify-center bg-neutral-100 p-4 dark:bg-neutral-900">17 <FlowForm onSubmit={handleSubmit} className="w-full max-w-xl" />18 </div>19 );20}