Component Name: reCaptcha¶
Last Updated: 2025-09-29 Source Code: https://bitbucket.org/i2cinc/i2c.salesforce.metadata/src/STAGING/force-app/main/default/lwc/reCaptcha
API Name: c-reCaptcha Type: Utility Component Target: Not exposed
Business Purpose¶
Integrates Google reCAPTCHA v2 (checkbox "I'm not a robot") into Salesforce forms to prevent spam and bot submissions. The component handles reCAPTCHA rendering, verification with Salesforce backend, responsive scaling, and lifecycle management.
User Interface¶
Visual Description¶
- Layout: Google reCAPTCHA badge (302x78px base size)
- Key UI Elements: Checkbox "I'm not a robot", badge image
- Responsive: Scales down on smaller screens using CSS transform
Component Structure¶
Files¶
reCaptcha.html- Template with div containerreCaptcha.js- Controller (82 lines)reCaptcha.js-meta.xml- Not exposed
JavaScript Controller¶
Properties¶
No @api properties
Event Handlers¶
grecaptchaVerified (document event)¶
- Calls ReCaptchaController.insertRecord with response token
- Dispatches "checked" event on success
- Console logs errors
grecaptchaExpired (document event)¶
- Dispatches "expired" event
window resize¶
- Calls applyScale() to maintain responsive sizing
Private Methods¶
applyScale()¶
Purpose: Dynamically scales reCAPTCHA to fit container using CSS transform Called By: renderedCallback, window resize event
renderedCallback()¶
Purpose: Renders reCAPTCHA using grecaptcha.render() via custom event Polling: Uses setInterval(100ms) to wait for grecaptcha global
Lifecycle¶
connectedCallback()¶
- Registers document event listeners (grecaptchaVerified, grecaptchaExpired)
- Registers window resize listener
disconnectedCallback()¶
- Removes window resize listener
Events¶
Events Dispatched¶
checked¶
- Fired when reCAPTCHA verification succeeds
- No detail payload
expired¶
- Fired when reCAPTCHA token expires
- No detail payload
Document Events Listened¶
grecaptchaRender¶
- Dispatched by component to trigger rendering
- Detail: { element, badge: "bottomright", size: "compact" }
grecaptchaVerified¶
- Dispatched by reCAPTCHA script after user verification
- Detail: { response: token }
grecaptchaExpired¶
- Dispatched when reCAPTCHA expires
Dependencies¶
Apex Classes¶
ReCaptchaController.insertRecord(): Verifies reCAPTCHA response with Google
External Scripts¶
- Google reCAPTCHA v2 script (loaded externally)
- Global
grecaptchaobject
Configuration¶
Not exposed - embedded component
Usage Examples¶
⚠️ Pre-Go-Live Concerns¶
CRITICAL - Fix Before Go-Live¶
- Polling with setInterval: Lines 40-51 poll every 100ms indefinitely until grecaptcha loads - should have timeout
- No cleanup of setInterval: If component unmounts before grecaptcha loads, interval leaks
HIGH - Address Soon After Go-Live¶
- No unit tests: Zero coverage
- Console.error in production: Line 19
- No loading state: User sees blank space while polling
- Hardcoded compact size: May not suit all form layouts
- Direct DOM manipulation: Uses getBoundingClientRect (could use ResizeObserver)
MEDIUM - Future Enhancement¶
- Add invisible reCAPTCHA option: Support invisible mode
- Make size configurable: Allow normal/compact via @api
Maintenance Notes¶
Complexity: Medium Recommended Review Schedule: Annually
Key Notes: - Requires external reCAPTCHA script to be loaded first - Polling interval could fail if script never loads (add timeout) - Responsive scaling uses CSS transform - works well but unusual approach - Event names use document-level custom events (not standard LWC pattern) - Component manages Google reCAPTCHA lifecycle
Browser Compatibility: - Chrome: Latest - Firefox: Latest - Safari: Latest - Mobile: iOS 12+, Android 8+ (reCAPTCHA supported)