Add Google reCAPTCHA v3 to your Laravel Forms

82 0 0 0

Last Updated : 2022-05-23 09:14:28

In this snippet I will explain how to add google reCAPTCHA v3 to your Laravel Forms

Hello guys, 

Google’s reCAPTCHA v3 was introduced in late 2018 and brings a range of benefits over reCAPTCHA v2 and its familiar “I’m not a robot” checkbox and “select all the traffic lights” style of challenges.

Instead of requiring the user to complete these challenges, v3 calculates a score based on a number of factors to determine whether the user is a human or not, then allows the website to take an appropriate action based on this score.

Google understandably hasn’t made public the factors that build up this score but it is believed to include:

  • User’s IP address

  • The user’s browser

  • Whether they are signed in to a Google account

And undoubtedly a number of other elements.

The benefits of v3 over v2 include:

  • Less interaction required by the end user

  • More effective at detecting bots

  • More flexibility for the website to take different actions depending on the returned score

So let's get started 

First Step : reCAPTCHA admin page (

1- got to reCAPTCHA admin page -> register a new site -> provide any label name you want -> choose reCAPTCHA type (v3) -> provide your domain(s) (localhost or any domain name) -> accepts terms -> then submit .

2- after submitting new site on reCAPTCHA admin page -> this will give you site key and secret key -> copy them (we will need them later).

Second Step : Your Laravel project

3- go to your form blade file -> add a hidden field in your form like this

<input type="hidden" name="recaptcha" id="recaptcha">

4- after adding recaptcha hidden field -> add this script to your form blade file like this

<script src="{{ config('services.recaptcha.sitekey') }}"></script>
grecaptcha.ready(function() {
grecaptcha.execute('{{ config('services.recaptcha.sitekey') }}', {action: 'submit'}).then(function(token) {
if (token) {
document.getElementById('recaptcha').value = token;

Note the {action: 'contact'} part, you can specify different actions for different parts of your website and see the data in your admin console.

Important, from Google’s docs: “actions may only contain alphanumeric characters and slashes, and must not be user-specific.”, this means you cannot use ‘contact-us’ for example, you’ll receive an error.

Also note the lines containing {{ config('services.recaptcha.sitekey') }}, you could simply paste your site key here, but it’s better to set these in config and env files.

5- open config/services.php and this code

'recaptcha' => [
'sitekey' => env('RECAPTCHA_SITEKEY'),
'secret' => env('RECAPTCHA_SECRET'),

6- in your .env file add this code

RECAPTCHA_SECRET=YOUR_RECAPTCHA_SECRET_KEY    // your secret key generated from reCAPTCHA admin page
RECAPTCHA_SITEKEY=YOUR_RECAPTCHA_SITE_KEY // your site key generated from reCAPTCHA admin page

7- in your controller that manages your contact form within the method that sends your form data for expample store() method in your ContactController add this code

* Store a newly created resource in storage.
* @param \App\Http\Requests\StoreMessageRequest $request
* @return \Illuminate\Http\Response
public function store(StoreMessageRequest $request)
$url = '';
$remoteip = $_SERVER['REMOTE_ADDR'];
$recapcha_data = [
'secret' => config('services.recaptcha.secret'),
'response' => $request->get('recaptcha'),
'remoteip' => $remoteip
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($recapcha_data)
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$resultJson = json_decode($result);
if ($resultJson->success != true) {
return back()->withErrors(['captcha' => 'ReCaptcha Error']);
if ($resultJson->score >= 0.3) {

// Validation was successful, add your form submission logic here
// This is my data logic
$data = $request->validated();
$message = Message::create([
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'],
'type_id' => $data['type_id'],
'description' => $data['description'],
if ($request->hasFile('file')) {
$file = $request->file('file');
$name = time().'-'.hexdec(\uniqid()).'.'.$file->getClientOriginalExtension();
$destinationPath = public_path('storage/messages/');
$file->move($destinationPath, $name);
$message->file = $name;
return response()->json(['success'=>'Created Successfully']);
// This is my data logic

} else {
return back()->withErrors(['captcha' => 'ReCaptcha Error']);


8- don't forget to modify your StoreMessageRequest file to include recaptcha field like this

* Get the validation rules that apply to the request.
* @return array
public function rules()
return [
'name' => 'required',
'email' => 'required_without:phone|email',
'phone' => 'sometimes|required_without:email',
'file' => 'sometimes|mimes:pdf|max:5048',
'description' => 'sometimes|nullable',
'type_id' => 'required',
'recaptcha' => 'required', // add this line to include recaptcha field in the request

Mahmoud Anwar

Mahmoud Anwar

Back End Developer with a passion for developing innovative web applications that expedite the efficiency and effectiveness of organizational success. Well-versed in technology and writing code to create systems that are reliable and user-friendly. Also has the proven ability to motivate, educate, and collaborate effectively to build web applications and effectively track changes. Confident communicator, strategic thinker, and innovative creator to develop software that is customized to meet a company’s organizational needs, highlight their core competencies, and further their success.