How to make Laravel 9 + Vue 3 + Inertia.js use Google ReCaptcha without installing a package

Everyone is so willing to add another unnecessary package to their project. But it’s not worth the clutter — let’s integrate ReCaptcha with a few config files.

Serdar Cevher
2 min readMay 20, 2022
  1. First, let’s create the resources/js/Composables/ReCaptcha.js file which will help us load the ReCaptcha API file occasionally:

2. Create a config file (config/recaptcha.php) and add your key and secret which you’ll grab from Google (Do not forget to put these values in your .env file):

<?phpreturn [
'key' => env('GOOGLE_RECAPTCHA_KEY', ''),
'secret' => env('GOOGLE_RECAPTCHA_SECRET’, '')
];

3. Next, create app/Validators/ReCaptcha.php to handle the validation job, with the following content:

4. Extend the Validator facade by adding the new validate method to the app/Providers/AppServiceProdiver.php’s boot method, named as ‘recaptcha’:

...
public function boot()
{
Validator::extend(
'recaptcha',
'App\\Validators\\ReCaptcha@validate'
);
...

5. Now pass the public key to your Vue.js template as the env() command you’re used from Blade files won’t work. So, in the same boot method of the AppServiceProvider, add it as:

Inertia::share([ 'config' => [
'google_recaptcha_key' => config('recaptcha.key'),
...
],
...

6. Now in your contact form, put the captcha element somewhere you like:

<div class="g-recaptcha" 
:data-sitekey="$page.props.config.google_recaptcha_key">
</div>

7. Load the ReCaptcha composable we have created in the first step. Then, assuming that your form is already sent via JavaScript, make your submit function grab the value prior to sending form data to the server:

8. Finally, extend your validation rules and feedback by adding the ‘recaptcha’ rule and relevant messages:

public function rules()
{
return [
'name' => 'required|max:100',
'email' => 'required|email',
'message' => 'required|max:1000',
'g-recaptcha-response' => 'required|recaptcha'
];
}
public function messages()
{
return [
//...
'g-recaptcha-response.required' => 'Your custom message',
'g-recaptcha-response.recaptcha' => 'Please prove that you are not a robot'
];
}

Voila, your contact form with the captcha validation is ready.

— -

Note that you can use this method to load the ReCaptcha element in a modal dialogue as well. All you have to do is to watch the isVisible prop of a modal and to call the useRecaptcha() method when it is changed to true.

The 3rd party script will be injected asynchronously and you will be expected to grab the validation result — please note that I noticed ReCaptcha result container ID was sometimes changing, so using the name attribute as document.getElementsByName(‘recaptcha-response’)[0] would probably be a better choice than depending on the ID.

--

--

Serdar Cevher

Developer of web & mobile apps | Co-founder: Auglinn, Off2Class | Founder: SmarDish, tarifmotoru.com, valizim.com | Ex columnist @PCnetDergisi