Newsletter Signup Form in React (No Backend Required)
Build a newsletter signup form without writing backend code. Email collection and spam protection included.
What We're Building
A newsletter signup form that:
- Collects email addresses
- Validates email format
- Prevents spam signups
- Stores subscribers in a dashboard
- Exports to CSV for your email service
- Works without backend code
The Quick Version
If you just want the code:
import { useFormFlow } from '@formflow.sh/react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
export function NewsletterForm() {
const { register, handleSubmit, formState } = useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => alert('Subscribed! Check your email.'),
});
return (
<form onSubmit={handleSubmit} className="flex gap-2 max-w-md">
<Input
{...register('email')}
type="email"
placeholder="Enter your email"
className="flex-1"
required
/>
<Button type="submit" disabled={formState.isSubmitting}>
{formState.isSubmitting ? 'Subscribing...' : 'Subscribe'}
</Button>
</form>
);
}That's it! 10 lines of code for a complete newsletter signup form.
Step-by-Step Tutorial
Step 1: Install FormFlow
npm install @formflow.sh/reactStep 2: Get Your API Key
Create a free account at formflow.sh and get your API key. Free tier includes 50 submissions per month.
Add to .env.local:
NEXT_PUBLIC_FORMFLOW_API_KEY=ff_live_your_key_hereStep 3: Create the Form
Create a new component NewsletterForm.tsx:
import { useFormFlow } from '@formflow.sh/react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
export function NewsletterForm() {
const { register, handleSubmit, formState } = useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => {
alert('Thanks for subscribing! Check your email.');
},
});
return (
<form onSubmit={handleSubmit} className="flex gap-2 max-w-md">
<Input
{...register('email')}
type="email"
placeholder="Enter your email"
className="flex-1"
required
/>
<Button type="submit" disabled={formState.isSubmitting}>
{formState.isSubmitting ? 'Subscribing...' : 'Subscribe'}
</Button>
</form>
);
}Step 4: Use It Anywhere
import { NewsletterForm } from '@/components/NewsletterForm';
export default function HomePage() {
return (
<div>
<h1>Subscribe to our newsletter</h1>
<NewsletterForm />
</div>
);
}Customization Options
Add Name Field
Collect names for personalized emails:
<form onSubmit={handleSubmit} className="space-y-4 max-w-md">
<div>
<Label htmlFor="email">Email *</Label>
<Input
{...register('email')}
id="email"
type="email"
placeholder="you@example.com"
required
/>
</div>
<div>
<Label htmlFor="name">Name (optional)</Label>
<Input
{...register('name')}
id="name"
placeholder="John Doe"
/>
</div>
<Button type="submit" disabled={formState.isSubmitting} className="w-full">
{formState.isSubmitting ? 'Subscribing...' : 'Subscribe'}
</Button>
</form>Add Success Message Component
Instead of alert, show a nice success message:
import { useState } from 'react';
export function NewsletterForm() {
const [submitted, setSubmitted] = useState(false);
const { register, handleSubmit, formState } = useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => {
setSubmitted(true);
},
});
if (submitted) {
return (
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
<h3 className="font-semibold text-green-900">
Thanks for subscribing!
</h3>
<p className="text-green-700 text-sm mt-1">
Check your email to confirm your subscription.
</p>
</div>
);
}
return (
<form onSubmit={handleSubmit}>
{/* form fields */}
</form>
);
}Add Email Validation
Custom email validation with error messages:
<Input
{...register('email', {
required: 'Email is required',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: 'Please enter a valid email address',
},
})}
type="email"
placeholder="Enter your email"
/>
{formState.errors.email && (
<p className="text-red-500 text-sm mt-1">
{formState.errors.email.message}
</p>
)}Styling Examples
Inline Form (Header/Footer)
<form onSubmit={handleSubmit} className="flex gap-2">
<Input
{...register('email')}
type="email"
placeholder="Your email"
className="max-w-xs"
/>
<Button type="submit">Subscribe</Button>
</form>Centered Hero Section
<div className="text-center max-w-2xl mx-auto py-20">
<h2 className="text-4xl font-bold mb-4">
Join our newsletter
</h2>
<p className="text-gray-600 mb-8">
Get weekly updates on React, forms, and web development.
</p>
<form onSubmit={handleSubmit} className="flex gap-2 justify-center">
<Input
{...register('email')}
type="email"
placeholder="Enter your email"
className="max-w-sm"
/>
<Button type="submit">Subscribe</Button>
</form>
</div>Sidebar Widget
<div className="bg-gray-50 rounded-lg p-6">
<h3 className="font-semibold mb-2">Newsletter</h3>
<p className="text-sm text-gray-600 mb-4">
Weekly React tips in your inbox.
</p>
<form onSubmit={handleSubmit} className="space-y-2">
<Input
{...register('email')}
type="email"
placeholder="Your email"
className="w-full"
/>
<Button type="submit" className="w-full">
Subscribe
</Button>
</form>
</div>Managing Subscribers
View Subscribers
All newsletter signups appear in your FormFlow dashboard at formflow.sh/submissions.
Export to CSV
Click "Export CSV" to download all subscribers. Import this into:
- Mailchimp
- ConvertKit
- SendGrid
- Any email service that accepts CSV
Email Notifications
Get notified when someone subscribes:
- Go to your FormFlow dashboard
- Click on "Settings"
- Enable email notifications
- Enter your email
Spam Protection
FormFlow automatically protects against spam with:
- Honeypot fields - Invisible fields that catch bots
- Rate limiting - Prevents automated signups
- Email validation - Ensures valid email format
Advanced: Double Opt-In
For compliance with GDPR and best practices, you can implement double opt-in by integrating with your email service (Mailchimp, SendGrid, etc.). FormFlow captures the initial submission, then your email service handles the confirmation flow:
const { register, handleSubmit } = useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => {
// Show message to check email
alert('Please check your email to confirm your subscription.');
},
});
// Then in your email service (Mailchimp, etc.):
// 1. Send confirmation email
// 2. User clicks link
// 3. Subscription confirmedCommon Use Cases
Blog Newsletter
Add to blog posts:
<div className="border-2 border-black rounded-lg p-6 my-8">
<h3 className="font-bold text-xl mb-2">
Enjoyed this post?
</h3>
<p className="text-gray-600 mb-4">
Get more content like this in your inbox every week.
</p>
<NewsletterForm />
</div>Product Waitlist
Collect emails before launch:
<div className="text-center py-20">
<h1 className="text-5xl font-bold mb-4">
Coming Soon
</h1>
<p className="text-xl text-gray-600 mb-8">
Be the first to know when we launch.
</p>
<NewsletterForm />
<p className="text-sm text-gray-500 mt-4">
{subscriberCount} people already signed up
</p>
</div>Footer Signup
Add to footer on every page:
<footer className="bg-black text-white py-12">
<div className="max-w-6xl mx-auto px-6">
<div className="grid md:grid-cols-2 gap-8 items-center">
<div>
<h3 className="text-2xl font-bold mb-2">
Stay Updated
</h3>
<p className="text-gray-400">
Join 10,000+ developers getting weekly tips.
</p>
</div>
<NewsletterForm />
</div>
</div>
</footer>Best Practices
1. Be Clear About What You're Sending
Tell users what to expect:
"Get weekly React tutorials. Unsubscribe anytime."2. Show Social Proof
"Join 10,000+ developers"3. Make Unsubscribe Easy
Include unsubscribe link in every email (most email services do this automatically).
4. Confirm Subscription
Show success message after signup:
"Thanks! Check your inbox for a confirmation email."Complete Example: Premium Newsletter Form
import { useState } from 'react';
import { useFormFlow } from '@formflow.sh/react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
export function PremiumNewsletterForm() {
const [submitted, setSubmitted] = useState(false);
const { register, handleSubmit, formState, reset } = useFormFlow({
apiKey: process.env.NEXT_PUBLIC_FORMFLOW_API_KEY,
onSuccess: () => {
setSubmitted(true);
reset(); // Clear form
},
});
if (submitted) {
return (
<div className="bg-green-50 border border-green-200 rounded-lg p-6 text-center">
<div className="text-green-600 text-5xl mb-3">ā</div>
<h3 className="font-bold text-xl text-green-900 mb-2">
You're all set!
</h3>
<p className="text-green-700">
Check your email to confirm your subscription.
</p>
<button
onClick={() => setSubmitted(false)}
className="text-green-800 underline text-sm mt-3"
>
Subscribe another email
</button>
</div>
);
}
return (
<div className="bg-white border-2 border-black rounded-lg p-6 max-w-md">
<h3 className="text-2xl font-bold mb-2">
Join 10,000+ Developers
</h3>
<p className="text-gray-600 mb-6">
Weekly React tips, tutorials, and news. Unsubscribe anytime.
</p>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<Label htmlFor="email">Email Address *</Label>
<Input
{...register('email', {
required: 'Email is required',
pattern: {
value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
message: 'Please enter a valid email',
},
})}
id="email"
type="email"
placeholder="you@example.com"
/>
{formState.errors.email && (
<p className="text-red-500 text-sm mt-1">
{formState.errors.email.message}
</p>
)}
</div>
<div>
<Label htmlFor="name">Name (optional)</Label>
<Input
{...register('name')}
id="name"
placeholder="John Doe"
/>
</div>
<Button
type="submit"
disabled={formState.isSubmitting}
className="w-full"
>
{formState.isSubmitting
? 'Subscribing...'
: 'Subscribe for Free'}
</Button>
<p className="text-xs text-gray-500 text-center">
No spam. Only high-quality content. Unsubscribe with one click.
</p>
</form>
</div>
);
}Conclusion
Building a newsletter signup form in React is simple with FormFlow:
- No backend code required
- Built-in spam protection
- Easy CSV export for email services
- Works with any UI library
- Free tier: 50 submissions/month
Related Resources
- Newsletter Form Solutions - Complete guide to newsletter signup options
- Form Validation Guide - Add validation to your forms