I added a simple message feature to my site that allows visitors to send me messages directly from the homepage. It’s just a text input field - no apps, phone numbers, accounts, or third-party services required.
What Are Cloudflare Workers and KV?
Cloudflare Workers are lightweight programs that run on Cloudflare’s global network. They handle web requests quickly and securely.
Cloudflare KV (Key-Value) is a simple database that stores data as key-value pairs. Perfect for storing small amounts of data like messages.
Why KV over D2? While Cloudflare D2 offers SQL capabilities, KV is better for this use case:
- Simple key-value lookups
- Lower latency
- More cost-effective for small data
Why This Approach?
- No barriers: No apps, accounts, or personal info required
- Works everywhere: Any device with a web browser
- Fast: Messages processed in milliseconds
- No dependencies: No external services
- Customizable: Easy to modify
- Free: No cost for personal use
How It Works
Three simple parts:
- Frontend: HTML form with text input
- Worker: JavaScript that processes messages
- Storage: Messages stored in Cloudflare KV
Frontend Form
1<form id="messageForm">
2 <input
3 type="text"
4 id="messageInput"
5 placeholder="Whisper something into the void..."
6 maxlength="200"
7 required
8 />
9 <button type="submit">Send</button>
10</form>
JavaScript Handler
1document.getElementById('messageForm').addEventListener('submit', async (e) => {
2 e.preventDefault();
3 const message = document.getElementById('messageInput').value.trim();
4
5 const response = await fetch('https://your-worker.workers.dev/message', {
6 method: 'POST',
7 headers: { 'Content-Type': 'application/json' },
8 body: JSON.stringify({ message })
9 });
10
11 const result = await response.json();
12 if (result.success) {
13 alert('Message sent!');
14 document.getElementById('messageInput').value = '';
15 }
16});
Worker Processing
The Worker handles:
- Validation: Checks message length/content
- Sanitization: Removes HTML/harmful content
- Metadata: Collects anonymous sender info
- Spam detection: Uses patterns to detect spam
- Storage: Saves to KV with unique ID
Data Collected
For transparency, here’s what’s collected with each message:
- Message content (sanitized, max 200 chars)
- Timestamp and unique ID
- IP address (for rate limiting only)
- Browser/device info (user agent)
- Location data (country, city, timezone from Cloudflare)
- Source page (referrer)
Spam Protection
Since this is a public form, spam protection is essential:
- Rate limiting: 10 messages per hour per IP
- Duplicate detection: Same message from same IP blocked
- Pattern matching: Common spam keywords flagged
- Bot detection: User agent analysis
- Input validation: Text only, character limits
- Auto-expiration: Messages deleted after 1 year
Future: Turnstile Integration
I’m considering adding Cloudflare Turnstile which is a privacy-preserving CAPTCHA alternative that verifies legitimate users without puzzles or data collection.
Setup Steps
- Create KV namespace for message storage
- Write Worker script in JavaScript
- Deploy Worker to Cloudflare
- Add form to homepage HTML
- Implement JavaScript to send data to Worker
Total setup time: ~2-3 hours including testing.
Technical Stack
- Frontend: Vanilla JavaScript + CSS
- Backend: Cloudflare Worker (JavaScript)
- Database: Cloudflare KV
- Deployment: Cloudflare dashboard
- Monitoring: Cloudflare Built-in analytics
~500 lines of code total, handles thousands of messages daily.