How to Implement Altcha CAPTCHA in Next.js: Privacy-First Form Protection
3 min read
Static Forms Team
Adding CAPTCHA protection to your Next.js forms doesn't have to be complicated. Altcha provides a privacy-focused solution that's easy to implement and doesn't track your users. Let's add it to a simple contact form.
What You Need
Before starting, make sure you have:
- Next.js application
- Pro subscription - Altcha needs Static Forms Pro
- API key - From your Static Forms account
Step 1: Install Altcha
npm install altcha
Step 2: Add Your API Key
Create a .env.local
file:
NEXT_PUBLIC_STATIC_FORMS_API_KEY=your_api_key_here
Step 3: Create a Simple Contact Form
Here's a basic contact form with Altcha verification:
'use client';
import { useState, useEffect } from 'react';
export default function ContactForm() {
const [isSubmitting, setIsSubmitting] = useState(false);
const [status, setStatus] = useState('');
// Load ALTCHA package
useEffect(() => {
import('altcha');
}, []);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const form = e.currentTarget;
setIsSubmitting(true);
try {
const formData = new FormData(form);
formData.append('apiKey', process.env.NEXT_PUBLIC_STATIC_FORMS_API_KEY || '');
const response = await fetch('https://api.staticforms.xyz/submit', {
method: 'POST',
body: formData,
});
if (response.ok) {
setStatus('Message sent successfully!');
form.reset();
// Reset ALTCHA widget
const altchaWidget = document.querySelector('altcha-widget') as any;
if (altchaWidget?.reset) {
altchaWidget.reset();
}
} else {
setStatus('Failed to send message. Please try again.');
}
} catch (error) {
setStatus('An error occurred. Please try again.');
} finally {
setIsSubmitting(false);
}
};
return (
<div className="max-w-md mx-auto p-6">
{status && (
<div className="mb-4 p-3 rounded bg-blue-50 text-blue-800">
{status}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block mb-2 font-medium">Name</label>
<input
type="text"
name="name"
required
className="w-full p-3 border rounded-md"
/>
</div>
<div>
<label className="block mb-2 font-medium">Email</label>
<input
type="email"
name="email"
required
className="w-full p-3 border rounded-md"
/>
</div>
<div>
<label className="block mb-2 font-medium">Message</label>
<textarea
name="message"
required
rows={4}
className="w-full p-3 border rounded-md"
/>
</div>
<div>
<label className="block mb-2 font-medium">Verify you're human</label>
<altcha-widget
challengeurl={`https://www.staticforms.xyz/api/altcha/challenge?apiKey=${process.env.NEXT_PUBLIC_STATIC_FORMS_API_KEY || ''}`}
name="altchaToken"
/>
</div>
<button
type="submit"
disabled={isSubmitting}
className="w-full py-3 bg-blue-600 text-white rounded-md disabled:bg-gray-400"
>
{isSubmitting ? 'Sending...' : 'Send Message'}
</button>
</form>
</div>
);
}
Step 4: Use the Component
Create a page to use your form:
// app/contact/page.tsx
import ContactForm from './ContactForm';
export default function ContactPage() {
return (
<div className="container mx-auto py-12">
<h1 className="text-3xl font-bold text-center mb-8">Contact Us</h1>
<ContactForm />
</div>
);
}
Step 5: Enable Altcha
- Go to your CAPTCHA settings
- Switch to "Altcha" tab
- Generate your keys
- Save settings
That's It!
Your form now has privacy-focused CAPTCHA protection. The widget automatically:
- ✅ Loads and verifies challenges
- ✅ Works without tracking users
- ✅ Protects against spam
- ✅ No puzzles for users to solve
Need Help?
- Get Pro access to use Altcha
- Configure settings in your account
- Read more guides