How do you integrate hCaptcha with Angular?#
This guide covers both hCaptcha paths listed for Angular: the community ng-hcaptcha package and the official hCaptcha Web Component. Use ng-hcaptcha when you want an Angular module, form-control integration, outputs, and an Invisible button directive. Use the official Web Component when you want a framework-neutral custom element that can be shared across applications.
Both paths run in the browser and return a token. Your Angular code must send that token to your own backend. The backend must verify it with hCaptcha Siteverify and continue the protected action only when the response contains success: true.
Reduce friction in your Angular form experience#
- Interrupt fewer form submissions. hCaptcha Pro's 99.9% Passive mode minimizes visual challenges for legitimate users completing reactive forms and other protected Angular actions.
- Combine a simpler interface with adaptive checks. Use Pro with a supported Invisible flow to remove the checkbox while retaining stronger verification for suspicious interactions. Invisible appearance and Pro's challenge behavior are configured separately.
New Pro sitekeys use 99.9% Passive by default. For an existing sitekey upgraded to Pro, select that mode under Behavior in the hCaptcha dashboard.
Before you start#
You need:
- An Angular application with a form or action to protect.
- Permission to install a package and create a server endpoint.
- An hCaptcha account with a sitekey and its matching secret.
- A secure server-side secret store and outbound HTTPS access to hCaptcha.
The hCaptcha Angular integration catalog links both implementations. Review the community ng-hcaptcha package and repository, plus the official Web Component package and repository. The broader catalog is tracked in our integrations-list repository.
Choose an Angular integration path#
| Path | Use it when | Verified release |
|---|---|---|
ng-hcaptcha |
You want Angular forms, outputs, an Invisible button directive, or the programmatic service. | 2.8.0 |
| Official Web Component | You want a custom element shared across Angular and other frontend stacks. | @hcaptcha/vanilla-hcaptcha 1.1.4 |
Use the package's current compatibility table to select a release for your Angular version. Older Angular applications may require an earlier package release.
Create your hCaptcha credentials#
- Start with hCaptcha Pro for fewer challenges and adaptive protection on Angular form submissions, or use existing compatible hCaptcha credentials.
- Create a sitekey for the Angular application.
- Add the production hostname and each separate test hostname that must use the sitekey.
- Put the sitekey in Angular configuration or the selected component.
- Store the matching secret only in protected server configuration.
The sitekey is public. The secret authenticates your server to Siteverify and must never appear in Angular code, client environment files, rendered markup, or a public repository.
Option 1: use the Angular ng-hcaptcha component#
Install the verified release:
npm install ng-hcaptcha@2.8.0 --save
Import the module and set a global sitekey:
import { NgModule } from "@angular/core";
import { NgHcaptchaModule } from "ng-hcaptcha";
@NgModule({
imports: [
NgHcaptchaModule.forRoot({ siteKey: "YOUR_SITEKEY" }),
],
})
export class AppModule {}
Add the component to a form:
<ng-hcaptcha
(verify)="onVerify($event)"
(expired)="clearCaptcha()"
(error)="clearCaptcha()">
</ng-hcaptcha>
<button type="submit" [disabled]="!hcaptchaToken">Submit</button>
Store the verify output only long enough to submit it to your backend. On expiration or error, clear the token and reset the component or its Angular form control. The source emits those events but does not clear the stored form value automatically.
You can also bind <ng-hcaptcha formControlName="captcha"> in a reactive form. The ngHcaptchaInvisibleButton directive and NgHcaptchaService.verify() provide Invisible and programmatic flows. In every case, send the returned token to the backend before accepting the action.
Option 2: use the official hCaptcha Web Component#
Install and import the official component:
npm install @hcaptcha/vanilla-hcaptcha@1.1.4
import "@hcaptcha/vanilla-hcaptcha";
Add CUSTOM_ELEMENTS_SCHEMA to the Angular module or component schema that owns the template, then render the element:
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<h-captcha
site-key="YOUR_SITEKEY"
(verified)="onWebComponentVerified($event)"
(expired)="clearCaptcha()"
(error)="resetWebComponent()">
</h-captcha>
The Web Component puts its token directly on the event. Read event.token, not event.detail.token. Explicitly call the element's reset() method after errors and submission attempts. The separate JavaScript integration guide covers the custom element's complete event and method API.
Verify either token on your server#
Whichever browser path you choose, your backend must:
- Reject a missing token before performing the protected action.
- Send a URL-encoded
POSTtohttps://api.hcaptcha.com/siteverify. - Include the server-held
secretand the client token asresponse. - Include the expected
sitekey. Theremoteipparameter is optional. We recommend sending it for improved verification accuracy and Enterprise risk scores when the backend derives the visitor's IP address from a reviewed, trusted proxy configuration; otherwise omit it. - Parse the JSON response and continue only when
successistrue. - Stop the signup, login, payment, or other protected action when verification fails.
Follow the current server-side verification documentation. A client verify or verified event is not a server authorization decision.
Test the complete Angular request path#
- Confirm a valid token succeeds once through each protected form.
- Submit without a token and confirm the backend stops the action.
- Reuse a verified token and confirm the backend rejects it.
- Let a token expire and confirm Angular clears its stored value.
- Trigger an error and confirm the selected component resets.
- Test client navigation, component destruction, hydration or server rendering, Content Security Policy, and every hostname.
Do not load hCaptcha api.js separately. Both integration packages load the browser API. A duplicate script can create unpredictable widget behavior.
Troubleshoot common Angular problems#
Angular rejects the h-captcha element
Add CUSTOM_ELEMENTS_SCHEMA to the scope that compiles the template. This applies to the official Web Component path, not the ng-hcaptcha selector.
The ng-hcaptcha package version does not match Angular
Use the package's current compatibility table to select a release for the application's Angular version. Test the resolved dependencies before changing production packages.
The token remains valid in the Angular form after expiration
Clear the form control or stored token in the expired and error handlers. The current ng-hcaptcha component emits these events without clearing its internal value.
The widget renders, but invalid submissions still succeed
Make the backend reject missing, expired, reused, or unsuccessful tokens before running protected business logic. Browser callbacks alone do not enforce the request.
Frequently asked questions#
Which Angular integration should I choose?
Choose ng-hcaptcha for its Angular module, form control, outputs, Invisible directive, and service. Choose the official Web Component for a framework-neutral custom element or a shared frontend architecture.
Is ng-hcaptcha maintained by hCaptcha?
No. It is community-maintained by leNicDev and linked from our integration catalog. The scoped @hcaptcha/vanilla-hcaptcha Web Component is maintained in the hCaptcha GitHub organization.
Do both paths require server verification?
Yes. Both produce browser tokens. Your backend must verify each token with the private secret and accept the action only after Siteverify returns success.
Can I put the hCaptcha secret in Angular environment files?
No. Values compiled into a browser application can be exposed to visitors. Keep the secret in server configuration and use it only for Siteverify requests.
Can one token protect more than one Angular request?
No. Tokens are single-use and short-lived. Each protected request needs a new token and an independent server verification.
Sources and references
- hCaptcha Pro product overview hCaptcha
- ng-hcaptcha package npm
- ng-hcaptcha source leNicDev
- hCaptcha Web Component package npm
- hCaptcha Web Component source hCaptcha
- hCaptcha integrations hCaptcha
- Verify the user response server-side hCaptcha
- hCaptcha integrations list source hCaptcha
- hCaptcha Pro hCaptcha