How to implement reCAPTCHA v3 in React
Today weāll show you how to implement reCAPTCHA v3 in React. There are many libraries that are available to add Google reCAPTCHA to the React application, but if possible the functionality should be implemented without external packages.
Here, we will use Google reCAPTCHA official document in a slightly different way. We have to finish this functionality in two parts. In this part, we will show you how to generate google reCAPTCHA v3 keys and how to implement them in the react application. Whereas in the second part, we will show you how to verify the response in the backend.
Google reCAPTCHA v3
- Part 1 - Implement reCAPTCHA v3 in React (You are hereā¦)
- Part 2 - Verify Google reCAPTCHA v3 using Node.js
Steps to implement reCAPTCHA v3 in React
- Generate google reCAPTCHA v3 keys
- Create a react application
- Add google reCAPTCHA in component
- API to verify reCAPTCHA response">Call a backend API to verify reCAPTCHA response
- Output
1. Generate google reCAPTCHA v3 keys
First, we have to generate reCAPTCHA v3 keys from which we will use the SITE KEY for the client side integration and the SECRET KEY for the server side integration. Use this link to generate keys. The following image will help you to create keys.
Generate reCAPTCHA Keys - How to implement reCAPTCHA v3 in React - Clue Mediator
Note: Donāt forget to add `localhost` in the Domains section for local development.
2. Create a react application
Letās create a simple react application using the `create-react-app` package. Run the following command to create a react app.
npx create-react-app react-recaptcha-v3
3. Add google reCAPTCHA in component
First, weāll create a simple form in the react component. We will submit the form data along with the reCAPTCHA token.
App.js
import { useState } from 'react';
function App() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [loading, setLoading] = useState(false);
const [response, setResponse] = useState(null);
const handleOnClick = e => {
}
return (
<div class="App">
<h3>reCAPTCHA v3 in React - <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3>
<div class="box">
<label>Name: </label>
<input type="text" onchange="{e" ==""> setName(e.target.value)} value={name} />
</div>
<div class="box">
<label>Email: </label>
<input type="text" onchange="{e" ==""> setEmail(e.target.value)} value={email} />
</div>
<button onclick={handleOnClick} disabled>{loading ? 'Submitting...' : 'Submit'}</button>
<br><br>
{response && <label>Output:<br><pre>{JSON.stringify(response, undefined, 2)}</pre></label>}
</div>
);
}
export default App;
Use the following CSS to design the form.
index.css
body {
margin: 0;
padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
.box {
margin: 15px;
}
.box label {
width: 50px;
display: inline-block;
text-align: right;
margin-right: 7px;
}
.box input {
padding: 5px 7px;
border-radius: 3px;
border: 1px solid #aaa;
width: 200px;
}
button {
cursor: pointer;
padding: 5px 10px;
margin-left: 73px;
border-radius: 3px;
border: 1px solid #aaa;
}
button:hover {
background: #ddd;
}
Now, we have to dynamically load the JavaScript API with your site key.
const SITE_KEY = "<your_site_key>";
...
...
useEffect(() => {
const loadScriptByURL = (id, url, callback) => {
const isScriptExist = document.getElementById(id);
if (!isScriptExist) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
script.id = id;
script.onload = function () {
if (callback) callback();
};
document.body.appendChild(script);
}
if (isScriptExist && callback) callback();
}
// load the script by passing the URL
loadScriptByURL("recaptcha-key", `https://www.google.com/recaptcha/api.js?render=${SITE_KEY}`, function () {
console.log("Script loaded!");
});
}, []);
</your_site_key>
Now, we have to execute the google reCAPTCHA on the submit button click. Once we receive the token we will submit the data.
const handleOnClick = e => {
e.preventDefault();
setLoading(true);
window.grecaptcha.ready(() => {
window.grecaptcha.execute(SITE_KEY, { action: 'submit' }).then(token => {
submitData(token);
});
});
}
const submitData = token => {
// call a backend API to verify reCAPTCHA response
}
4. Call a backend API to verify reCAPTCHA response
In the final step, we have to call a backend API to pass the reCAPTCHA response along with the form data. Whereas in the backend, we have to verify the response using SECRET KEY. Weāll show you that step in the upcoming article.
const submitData = token => {
// call a backend API to verify reCAPTCHA response
fetch('http://localhost:4000/verify', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": name,
"email": email,
"g-recaptcha-response": token
})
}).then(res => res.json()).then(res => {
setLoading(false);
setResponse(res);
});
}
5. Output
Letās combine all code together and see how it looks.
App.js
import { useEffect, useState } from 'react';
const SITE_KEY = "<your_site_key>";
function App() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [loading, setLoading] = useState(false);
const [response, setResponse] = useState(null);
useEffect(() => {
const loadScriptByURL = (id, url, callback) => {
const isScriptExist = document.getElementById(id);
if (!isScriptExist) {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
script.id = id;
script.onload = function () {
if (callback) callback();
};
document.body.appendChild(script);
}
if (isScriptExist && callback) callback();
}
// load the script by passing the URL
loadScriptByURL("recaptcha-key", `https://www.google.com/recaptcha/api.js?render=${SITE_KEY}`, function () {
console.log("Script loaded!");
});
}, []);
const handleOnClick = e => {
e.preventDefault();
setLoading(true);
window.grecaptcha.ready(() => {
window.grecaptcha.execute(SITE_KEY, { action: 'submit' }).then(token => {
submitData(token);
});
});
}
const submitData = token => {
// call a backend API to verify reCAPTCHA response
fetch('http://localhost:4000/verify', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": name,
"email": email,
"g-recaptcha-response": token
})
}).then(res => res.json()).then(res => {
setLoading(false);
setResponse(res);
});
}
return (
<div class="App">
<h3>reCAPTCHA v3 in React - <a href="https://www.cluemediator.com/" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3>
<div class="box">
<label>Name: </label>
<input type="text" onchange="{e" ==""> setName(e.target.value)} value={name} />
</div>
<div class="box">
<label>Email: </label>
<input type="text" onchange="{e" ==""> setEmail(e.target.value)} value={email} />
</div>
<button onclick={handleOnClick} disabled>{loading ? 'Submitting...' : 'Submit'}</button>
<br><br>
{response && <label>Output:<br><pre>{JSON.stringify(response, undefined, 2)}</pre></label>}
</div>
);
}
export default App;
</your_site_key>
Run the project and check the output in the browser.
Output - How to implement reCAPTCHA v3 in React - Clue Mediator
Thatās it for today.
Thank you for reading. Happy Coding..!!