Skip to content

Adding ReCaptcha to a Wagtail site

July 12, 2025 | 11:07 AM

Adding ReCaptcha to a Wagtail site

My wife has a site for her homeschool concert band that she teaches. It has a typical contact form for people to fill out and she can email them with information and such about the band and classes and requirements etc.
The site has been found by a bot that sends so much junk email that it began taking hours to sift through the messages to see what was “real” and what were spam from bots.

So, I decided it was time to add ReCaptcha to the site to stem the flow of spam… at least a little.

What is ReCaptcha?

According to Google, “reCAPTCHA is a free service from Google that helps protect websites from spam and abuse. A “CAPTCHA” is a turing test to tell human and bots apart. It is easy for humans to solve, but hard for “bots” and other malicious software to figure out. By adding reCAPTCHA to a site, you can block automated software while helping your welcome users to enter with ease.”

So I signed up and setup the ReCaptcha service for her site and for localhost for testing. This is a pretty straightforward process.

Make sure you save the keys somewhere so you can add them to the .env later.

Adding ReCaptcha to Wagtail

I followed (this tutorial)[https://learnwagtail.com/tutorials/contact-forms/] for the contact form when I created the site. So I naturally used the (follow-on tutorial)[https://learnwagtail.com/tutorials/adding-recaptcha-to-your-contact-forms/] for the reCAPTCHA setup.
Full discloser, I didn’t watch the videos. I just followed the tutorial and it was a pretty straightforward process except for one tiny thing that took about an hour to figure out.

Add ReCaptcha to the Contact Form


INSTALLED_APPS = [
# ... other apps, left out for brevity ...
    "captcha",
    "django_recaptcha", # this guy here is not called out in the tutorial, but is very required and took a long time to find.
    "wagtailcaptcha",
# ... other apps, left out for brevity ...

about 50 lines down in the same file. I added the ReCaptcha keys to the settings, and had them reference the sourced .env file. There is a type exception happening, so I effectivly cast the retrieved .env values as strings.

RECAPTCHA_PUBLIC_KEY = str(os.environ.get("RECAPTCHA_PUBLIC_KEY"))
RECAPTCHA_PRIVATE_KEY = str(os.environ.get("RECAPTCHA_PRIVATE_KEY"))
NOCAPTCHA = True
from wagtailcaptcha.models import WagtailCaptchaEmailForm

# ... existing code, left out for brevity ...

and I changed the ContactPage to extend WagtailCaptchaEmailForm instead of AbstractEmailForm.

# BEFORE
class ContactPage(AbstractEmailForm):
#AFTER
class ContactPage(WagtailCaptchaEmailForm):