Install hCaptcha in Angular with backend verification
As you already know, it is essential to have a system in public web projects that reduces spam, fake users and automated abuse. Google reCAPTCHA, hCaptcha and Cloudflare Turnstile solve that problem with different trade-offs around privacy, user friction, provider ecosystem and backend verification.
This guide keeps the original hCaptcha example, but the current recommendation is broader: choose the anti-bot provider according to the form risk, the privacy requirements and the backend you can maintain.
In this article we are going to show how to install hCaptcha step by step in an Angular project and how to keep the secure part of the decision in the backend.
hCaptcha, reCAPTCHA and Turnstile
These tools solve a similar problem but they do not have the same trade-offs. Google reCAPTCHA is familiar and widely documented, hCaptcha focuses on privacy and independent CAPTCHA infrastructure, and Cloudflare Turnstile tries to reduce visible challenges by using browser and risk signals. In every case, the secure pattern is the same: the Angular app receives a token, but the backend must verify that token before trusting the request.
For an Angular SSR app, the widget must only render in the browser. The server-rendered HTML should still contain the tutorial content, while the CAPTCHA script and browser-only component are delayed until hydration.
hCaptcha verification should follow the same production rule as reCAPTCHA and Turnstile: the Angular app sends the response token to your backend, and the backend validates it with hCaptcha's siteverify endpoint before processing the form. Do not expose the secret key in Angular, even in examples.
Here is the repository https://github.com/al118345/ejemplo-hcaptcha-en-angular-universal for reference and the following explanatory video:
Why hCaptcha
The following list summarizes common reasons to evaluate hCaptcha instead of using reCAPTCHA by default.- Provider independence: it is an alternative to relying only on Google reCAPTCHA.
- Privacy positioning: it is often evaluated by teams that want a different privacy profile.
- Backend verification: like any CAPTCHA, its result should be verified on the server before trusting a form submission.

Register in hCaptcha
In this article we assume that you already have a Gmail account.
The first step is to register at https://hCaptcha.com/?r=335d4419fb51. Once you access the site and log in with your Gmail account, the following view will appear.

Or from the sites view:

Once inside, we must fill in the form with the domain where we are going to execute it. Below is the example applied to the website 1938.com.es.

Once the form has been completed, the following screen appears with information about the key used to operate the service.

If we click on settings, we can consult the public key to use in our project. Clicking this button takes us to the following tab:

We also need the private key, so we must access the settings tab to obtain it as shown below.

Finally, the private key is located in the settings tab:

Important: for localhost tests, you can use:
- Site Key: 10000000-ffff-ffff-ffff-000000000001
- Secret Key: 0x0000000000000000000000000000000000000000
Installation
To perform this installation, the project must be split into a frontend and a backend. The frontend will handle user interaction and the backend will communicate with hCaptcha.
From Angular, we install the ng-hcaptcha package with the following command:
In addition, we create the following service to communicate with the Python API.
We import the module into our app with the following code:
And we add the functionality in the component.html:
And in the component.ts:
Finally, we modify the API so it can receive the frontend request by creating the following route in the project https://github.com/al118345/envio_email_api_python.
To finish, at https://dashboard.hcaptcha.com/overview you can consult a view like the following image where you can check how much revenue you have obtained.

Running example
Are you a robot? According to hCaptcha:
You are a robot, solve the CAPTCHA
Angular Universal
If you want to install it in an Angular SSR application, add a small check to avoid server-side rendering problems.
For older Angular Universal projects this command was common. In current Angular projects, prefer the official @angular/ssr setup:
ng add @nguniversal/express-engine
If you get an error like:
ERESOLVE unable to resolve dependency tree
Do not worry. Alternate between this command:
npm install --force @nguniversal/express-engine
and then:
ng add @nguniversal/express-engine
Repeat those last two steps as many times as necessary until the error disappears.
First, here is the code from the component.ts where the logic is added to detect whether it is running on the server side or in the browser.
You may get an error on line 2, @Inject(PLATFORM_ID) private platformId, such as:
TS7006: Parameter 'platformId' implicitly has an 'any' type.
In that case, add the following line to the tsconfig.json file:
And now add the required code in the view, component.html, to avoid the server-rendering problem.
Related security tutorials: Cloudflare Turnstile with Angular and FastAPI, Google reCAPTCHA in Angular and protecting an Angular API with Nginx and FastAPI.