Using reCAPTCHA on a Astro form
Here’s how I used Recaptcha on a Astro 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:
<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:
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
}
}
I wrote 17 books to help you become a better developer, download them all at $0 cost by joining my newsletter
JOIN MY CODING BOOTCAMP, an amazing cohort course that will be a huge step up in your coding career - covering React, Next.js - next edition February 2025