# Using reCAPTCHA on a Astro form

> Learn how to add Google reCAPTCHA to an Astro form to stop spam, wiring the widget with your site key and verifying the response on the server with siteverify.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2024-09-14 | Topics: [Astro](https://flaviocopes.com/tags/astro/) | Canonical: https://flaviocopes.com/using-recaptcha-on-a-astro-form/

Here’s how I used Recaptcha on a [Astro](https://flaviocopes.com/astro-introduction/) form to prevent spam and form submission abuse.

Set Recaptcha first, and grab the `RECAPTCHA_SITE_KEY` and `RECAPTCHA_SECRET_KEY` variables, put them in `.env` or anywhere you manage env vars.

Then in the Astro component:

```javascript
<script
  is:inline
  src='https://www.google.com/recaptcha/api.js'></script>
<script is:inline>
  function recaptcha() {
    document.querySelector('form').submit()
  }
</script>

<form method='post'>
 ...
  <input
    type='submit'
    class='block w-full px-3 py-2 mt-8 text-sm font-semibold text-center text-white cursor-pointer leading-6 rounded-md g-recaptcha focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 ring-1 ring-inset ring-blue-200 hover:ring-blue-300 hover:bg-blue-600'
    data-sitekey={import.meta.env
      .RECAPTCHA_SITE_KEY ||
      process.env.RECAPTCHA_SITE_KEY}
    data-callback='recaptcha'
    data-action='submit'
    value='Login'
  />
</form>
```

Server-side form POST request handler:

```javascript
export async function processCaptcha(g_recaptcha_response: string) {
  const url =
    'https://www.google.com/recaptcha/api/siteverify'

  const requestBody = new URLSearchParams({
    secret:
      import.meta.env.RECAPTCHA_SECRET_KEY ||
      process.env.RECAPTCHA_SECRET_KEY,
    response: g_recaptcha_response
  })

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: requestBody.toString()
  })

  const data = await response.json()

  console.log(data)
  /*
  {
    success: true,
    challenge_ts: '2024-01-20T18:18:12Z',
    hostname: 'localhost',
    score: 0.9,
    action: 'submit'
  }
  */

  return data.success
}

if (Astro.request.method === 'POST') {
  const formData = await Astro.request.formData()

  const email = formData.get('email')?.toString() || ''
  const password =
    formData.get('password')?.toString() || ''
  const g_recaptcha_response =
    formData.get('g-recaptcha-response')?.toString() || ''

  const is_valid_captcha = await processCaptcha(g_recaptcha_response)

  if (!is_valid_captcha) {
    error = 'Invalid captcha'
  } else {
		//valid
  }
}
```
