Newsletter
Email signup form for capturing leads.
Usage
import { Newsletter } from '@/components/landing';
<Newsletter />
Location: src/components/landing/Newsletter.tsx
Features
- Email input + submit button
- Privacy disclaimer
- Scroll animation
⚠️
Note
This component is visual only - no backend integration. Connect to your email provider (Resend, Mailchimp, etc.) as needed.
Customization
i18n
Update translations:
{
"landing": {
"newsletter": {
"title": "Stay in the loop",
"subtitle": "Get product updates and tips delivered to your inbox",
"placeholder": "Enter your email",
"button": "Subscribe",
"privacy": "We respect your privacy. Unsubscribe at any time."
}
}
}
Backend Integration
With Resend
'use client';
import { useState } from 'react';
import { Button, Input } from '@/components/ui';
export default function Newsletter() {
const [email, setEmail] = useState('');
const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setStatus('loading');
try {
const response = await fetch('/api/newsletter', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
if (response.ok) {
setStatus('success');
setEmail('');
} else {
setStatus('error');
}
} catch {
setStatus('error');
}
};
return (
<form onSubmit={handleSubmit} className="flex gap-2 max-w-md mx-auto">
<Input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Enter your email"
required
disabled={status === 'loading'}
/>
<Button type="submit" color="dark" disabled={status === 'loading'}>
{status === 'loading' ? 'Subscribing...' : 'Subscribe'}
</Button>
</form>
);
}
API Route (Backend)
# app/api/v1/newsletter/router.py
from fastapi import APIRouter
from pydantic import BaseModel, EmailStr
import resend
router = APIRouter()
class NewsletterSubscribe(BaseModel):
email: EmailStr
@router.post("/subscribe")
async def subscribe(data: NewsletterSubscribe):
resend.api_key = settings.RESEND_API_KEY
# Add to audience/list
resend.Contacts.create(
email=data.email,
audience_id="your-audience-id"
)
return {"message": "Subscribed successfully"}
Example Layout
<section className="py-20 bg-zinc-900 dark:bg-zinc-950">
<div className="container mx-auto px-4">
<div className="max-w-2xl mx-auto text-center">
<h2 className="text-3xl font-bold text-white mb-4">
{t('title')}
</h2>
<p className="text-zinc-400 mb-8">
{t('subtitle')}
</p>
<form className="flex flex-col sm:flex-row gap-4 justify-center">
<Input
type="email"
placeholder={t('placeholder')}
className="sm:w-80"
/>
<Button color="light">{t('button')}</Button>
</form>
<p className="text-xs text-zinc-500 mt-4">
{t('privacy')}
</p>
</div>
</div>
</section>