TABLE OF CONTENTS
Introduction
This document defines the standard implementation approach for integrating and reusing Google reCAPTCHA functionality across Znode Storefront pages and forms.
When to Use reCAPTCHA
Recommended Use Cases
Public-Facing Forms
- Login
- Registration
- Contact forms
- Password reset
- Newsletter or feedback forms
Sensitive Operations
- Account updates
- Payment-related workflows
- Any bot-prone operations
Compliance Requirements
- Product-mandated security flows
- Regulatory requirements
When Not to Use reCAPTCHA
On trusted internal tools (unless explicitly required)
- Where implementation negatively impacts user experience without sufficient risk justification
Architecture and Implementation Overview
Component Structure
Layer | Location | Responsibility |
UI Component | packages/base-components/src/Recaptcha/Recaptcha.tsx | Renders widget and handles user interaction |
Utilities | packages/utils/src/recaptcha.ts | Script loading and token handling |
Configuration | .env | Site and secret key management |
Supported Versions
Version | Type | Description |
v3 | Invisible | Score-based, no UI interaction |
Integration Guide
Import Component
import Recaptcha from '@our-org/base-components/Recaptcha';
Add Component to Form
<Recaptcha siteKey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY} version="v3" onVerify={handleRecaptcha} onError={handleRecaptchaError}
/>
HTML
Props Reference
Prop | Type | Required | Description |
siteKey | string | Yes | reCAPTCHA site key |
version | 'v3' | No | Default is v3 |
onVerify | function | Yes | Returns token |
onError | function | No | Handles error or expiry |
theme | 'light' or 'dark' | No | UI theme |
Handle Token
const [recaptchaToken, setRecaptchaToken] = useState(''); const handleRecaptcha = (token: string) => { setRecaptchaToken(token); }; const handleRecaptchaError = (error: string) => { console.error(error); };
HTML
Submit Form with Token
const handleSubmit = async (e) => { e.preventDefault(); if (!recaptchaToken) { // Show validation error return; } await api.submitForm({ ...formData, recaptchaToken, }); };
HTML
Backend Verification (Mandatory)
Never trust frontend tokens without backend verification. const axios = require('axios'); const verifyRecaptcha = async (token) => { const { data } = await axios.post( 'https://www.google.com/recaptcha/api/siteverify', null, { params: { secret: process.env.RECAPTCHA_SECRET_KEY, response: token, }, } ); return data.success; };
HTML
Utility Functions
import { loadRecaptchaScript, resetRecaptcha, } from '@our-org/utils/recaptcha'; useEffect(() => { loadRecaptchaScript(siteKey, version); return () => { resetRecaptcha(); }; }, []);
HTML
Environment Configuration
Frontend
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=your_site_key
HTML
Backend
RECAPTCHA_SECRET_KEY=your_secret_key
HTML
Rules
- Never hardcode keys
- Always use environment variables
- Use separate keys for development, staging, and production
Best Practices
- Use the shared reCAPTCHA component only
- Avoid duplicating logic
- Always handle:
- Token expiry
- Errors
- Ensure:
- Accessibility (keyboard support)
- Proper UI visibility
- Accessibility (keyboard support)
- Proper UI visibility
- Always verify tokens on the backend
- Keep implementation modular and reusable
Troubleshooting Guide
Issue | Possible Cause | Resolution |
Widget not rendering | Invalid or missing site key | Verify environment variables and script loading |
Token not received | onVerify not triggered | Debug JavaScript errors |
Backend verification fails | Invalid or expired token | Validate secret key and token lifecycle |
UI issues | CSS overlap | Inspect layout and styles |