google-recaptcha-v3
v1.1.2
Published
A React library for Google reCAPTCHA integration with both hooks and components supporting v2 and v3
Maintainers
Readme
React Google Recaptcha
A clean, modern React library for Google reCAPTCHA integration with both hooks and components supporting v2 and v3.
Install:
npm i google-recaptcha-v3Import to React:
Hook (v3 only):
import { useGoogleRecaptcha } from "google-recaptcha-v3";Component (supports both v2 and v3):
import { GoogleRecaptcha } from "google-recaptcha-v3";Hook Usage (v3 only)
Basic Hook Usage
import React from "react";
import { useGoogleRecaptcha } from "google-recaptcha-v3";
const YourComponent = () => {
const siteKey = "YOUR_SITE_KEY";
const action = "submit";
const { token, error, isLoading } = useGoogleRecaptcha(siteKey, action);
if (isLoading) {
return <div>Loading reCAPTCHA...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
// You can use token to send request to API
return (
<div>
{token && <p>reCAPTCHA token generated successfully!</p>}
</div>
);
};
export default YourComponent;Component Usage
reCAPTCHA v2 - Basic Usage
import React, { useRef } from "react";
import { GoogleRecaptcha, GoogleRecaptchaRef } from "google-recaptcha-v3";
const YourComponent = () => {
const recaptchaRef = useRef<GoogleRecaptchaRef>(null);
const siteKey = "YOUR_SITE_KEY";
const handleSubmit = async () => {
if (recaptchaRef.current) {
const token = await recaptchaRef.current.execute();
if (token) {
console.log("reCAPTCHA token:", token);
// Send request to your API with the token
}
}
};
const handleChange = (token: string | null) => {
console.log("reCAPTCHA token changed:", token);
};
return (
<div>
<GoogleRecaptcha
ref={recaptchaRef}
sitekey={siteKey}
onChange={handleChange}
onExpired={() => console.log("reCAPTCHA expired")}
onErrored={(error) => console.error("reCAPTCHA error:", error)}
/>
<button onClick={handleSubmit}>Submit</button>
</div>
);
};
export default YourComponent;reCAPTCHA v2 - Advanced Configuration
import React, { useRef } from "react";
import { GoogleRecaptcha, GoogleRecaptchaRef } from "google-recaptcha-v3";
const YourComponent = () => {
const recaptchaRef = useRef<GoogleRecaptchaRef>(null);
const siteKey = "YOUR_SITE_KEY";
const handleSubmit = async () => {
const token = recaptchaRef.current?.getResponse();
if (token) {
// Send request to your API with the token
console.log("Submitting with token:", token);
} else {
alert("Please complete the reCAPTCHA");
}
};
const handleReset = () => {
recaptchaRef.current?.reset();
};
return (
<div>
<GoogleRecaptcha
ref={recaptchaRef}
sitekey={siteKey}
theme="dark"
size="compact"
hl="vi" // Vietnamese
onChange={(token) => console.log("Token:", token)}
onExpired={() => {
console.log("reCAPTCHA expired");
handleReset();
}}
onErrored={(error) => console.error("Error:", error)}
style={{ margin: "20px 0" }}
/>
<div>
<button onClick={handleSubmit}>Submit</button>
<button onClick={handleReset}>Reset</button>
</div>
</div>
);
};
export default YourComponent;reCAPTCHA v3 - Component Usage
import React, { useRef } from "react";
import { GoogleRecaptcha, GoogleRecaptchaRef } from "google-recaptcha-v3";
const YourComponent = () => {
const recaptchaRef = useRef<GoogleRecaptchaRef>(null);
const siteKey = "YOUR_SITE_KEY";
const handleSubmit = async () => {
try {
const token = await recaptchaRef.current?.executeAsync();
if (token) {
console.log("v3 token:", token);
// Send request to your API with the token
}
} catch (error) {
console.error("Failed to get token:", error);
}
};
return (
<div>
<GoogleRecaptcha
ref={recaptchaRef}
sitekey={siteKey}
version="v3"
action="submit"
onLoad={() => console.log("reCAPTCHA v3 loaded")}
onErrored={(error) => console.error("reCAPTCHA error:", error)}
/>
<button onClick={handleSubmit}>Submit with v3</button>
</div>
);
};
export default YourComponent;Invisible reCAPTCHA
import React, { useRef } from "react";
import { GoogleRecaptcha, GoogleRecaptchaRef } from "google-recaptcha-v3";
const YourComponent = () => {
const recaptchaRef = useRef<GoogleRecaptchaRef>(null);
const siteKey = "YOUR_SITE_KEY";
const handleSubmit = async () => {
try {
// For invisible reCAPTCHA, execute when user submits
const token = await recaptchaRef.current?.executeAsync();
if (token) {
console.log("Invisible reCAPTCHA token:", token);
// Send request to your API with the token
}
} catch (error) {
console.error("Failed to execute invisible reCAPTCHA:", error);
}
};
return (
<div>
<GoogleRecaptcha
ref={recaptchaRef}
sitekey={siteKey}
size="invisible"
badge="bottomright"
onLoad={() => console.log("Invisible reCAPTCHA loaded")}
onErrored={(error) => console.error("Error:", error)}
/>
<button onClick={handleSubmit}>Submit (Invisible reCAPTCHA)</button>
</div>
);
};
export default YourComponent;Advanced Hook Usage
import React from "react";
import { useGoogleRecaptcha, ReCaptchaOptions } from "google-recaptcha-v3";
const YourComponent = () => {
const siteKey = "YOUR_SITE_KEY";
const action = "submit";
const options: ReCaptchaOptions = { language: "vi" }; // Vietnamese language
const {
token,
error,
isLoading,
refreshToken,
executeRecaptcha
} = useGoogleRecaptcha(siteKey, action, options);
const handleSubmit = async () => {
try {
const newToken = await executeRecaptcha();
if (newToken) {
// Send request to your API with the token
console.log("New token:", newToken);
}
} catch (err) {
console.error("Failed to get reCAPTCHA token:", err);
}
};
return (
<div>
<button onClick={handleSubmit} disabled={isLoading}>
{isLoading ? "Loading..." : "Submit"}
</button>
<button onClick={refreshToken} disabled={isLoading}>
Refresh Token
</button>
{error && <p style={{ color: "red" }}>Error: {error}</p>}
{token && <p style={{ color: "green" }}>Token ready!</p>}
</div>
);
};
export default YourComponent;API Reference
Hook API
useGoogleRecaptcha(siteKey, action, options?)
Parameters:
siteKey(string): Your Google reCAPTCHA v3 site keyaction(string): The action name for this reCAPTCHA executionoptions(ReCaptchaOptions, optional): Configuration optionslanguage(string, optional): Language code (default: "en")
Returns:
token(string | null): The reCAPTCHA tokenerror(string | null): Error message if something went wrongisLoading(boolean): Loading staterefreshToken(function): Function to refresh the tokenexecuteRecaptcha(function): Function to manually execute reCAPTCHA
Component API
<GoogleRecaptcha /> Props
Required Props:
sitekey(string): Your Google reCAPTCHA site key
Optional Props:
version("v2" | "v3"): reCAPTCHA version (default: "v2")theme("light" | "dark"): Visual theme (v2 only, default: "light")size("compact" | "normal" | "invisible"): Widget size (default: "normal")type("image" | "audio"): Challenge type (v2 only, default: "image")action(string): Action name for v3 (default: "submit")hl(string): Language code (default: "en")badge("bottomright" | "bottomleft" | "inline"): Badge position for invisible (default: "bottomright")tabindex(number): Tab index for accessibilityisolated(boolean): Isolated modeclassName(string): CSS class namestyle(React.CSSProperties): Inline styles
Callback Props:
onChange((token: string | null) => void): Called when token changesonExpired(() => void): Called when token expiresonErrored((error: Error) => void): Called when error occursonLoad(() => void): Called when reCAPTCHA loads
Component Ref Methods
When using useRef<GoogleRecaptchaRef>():
execute(): Promise<string | null> - Execute reCAPTCHA and get tokenexecuteAsync(): Promise - Execute reCAPTCHA and get token (throws on failure)reset(): void - Reset the reCAPTCHA widget (v2 only)getResponse(): string | null - Get current response token (v2 only)
TypeScript Support
This package includes full TypeScript support with exported interfaces:
import { useGoogleRecaptcha, ReCaptchaResponse, ReCaptchaOptions } from "google-recaptcha-v3";Features
Hook Features (v3 only)
- ✅ Clean and modern React hook
- ✅ Full TypeScript support
- ✅ Automatic script loading and cleanup
- ✅ Error handling
- ✅ Loading states
- ✅ Manual token refresh
- ✅ Language support
- ✅ Zero dependencies (peer dependency: React >=16.8.0)
Component Features (v2 & v3)
- ✅ Supports both reCAPTCHA v2 and v3
- ✅ Full component-based implementation with ref support
- ✅ All reCAPTCHA v2 props (theme, size, type, etc.)
- ✅ Invisible reCAPTCHA support
- ✅ Comprehensive callback handling (onChange, onExpired, onErrored, onLoad)
- ✅ Imperative API through refs (execute, reset, getResponse)
- ✅ Flexible styling and positioning options
- ✅ Language and localization support
- ✅ Full TypeScript interfaces and type safety
Backend Integration
Verify reCAPTCHA token from React with NestJS Back-End:
Create RecaptchaMiddleware by CMD:
nest generate middleware recaptchaAdd Sample code to RecaptchaMiddleware:
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import axios from 'axios';
@Injectable()
export class RecaptchaMiddleware implements NestMiddleware {
private key = 'YOUR_SITE_SECRET_KEY';
async use(req: Request, res: Response, next: NextFunction) {
const recaptchaToken = req.body.recaptchaToken;
if (!recaptchaToken) {
return res.status(400).json({ message: 'Missing recaptchaToken' });
}
try {
const response = await axios.post(
`https://www.google.com/recaptcha/api/siteverify?secret=${this.key}&response=${recaptchaToken}`,
{},
);
const { success } = response.data;
if (!success) {
return res.status(401).json({ message: 'Invalid recaptchaToken' });
}
next();
} catch (error) {
console.error('Recaptcha verification error:', error);
return res.status(500).json({ message: 'Internal Server Error' });
}
}
}Author
Copyright 2024 mia nguyen x thind9xdev
Licensed under the MIT License
