{"id":13481823,"url":"https://github.com/DethAriel/ng-recaptcha","last_synced_at":"2025-03-27T12:31:38.894Z","repository":{"id":37963063,"uuid":"64790881","full_name":"DethAriel/ng-recaptcha","owner":"DethAriel","description":"Angular component for Google reCAPTCHA","archived":false,"fork":false,"pushed_at":"2024-06-15T06:45:34.000Z","size":4259,"stargazers_count":472,"open_issues_count":18,"forks_count":123,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-10-12T11:35:08.582Z","etag":null,"topics":["angular-recaptcha","captcha","google-recaptcha","ng-recaptcha","recaptcha-api"],"latest_commit_sha":null,"homepage":"https://dethariel.github.io/ng-recaptcha/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DethAriel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-02T20:37:04.000Z","updated_at":"2024-09-28T09:13:43.000Z","dependencies_parsed_at":"2023-11-23T05:40:28.498Z","dependency_job_id":"96da5d60-912c-415f-b36a-b8eed4e3f429","html_url":"https://github.com/DethAriel/ng-recaptcha","commit_stats":{"total_commits":381,"total_committers":18,"mean_commits":"21.166666666666668","dds":"0.11023622047244097","last_synced_commit":"e32d5aa8b078c78e28d4067090e6c26ea70ae36b"},"previous_names":["dethariel/ng2-recaptcha"],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DethAriel%2Fng-recaptcha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DethAriel%2Fng-recaptcha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DethAriel%2Fng-recaptcha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DethAriel%2Fng-recaptcha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DethAriel","download_url":"https://codeload.github.com/DethAriel/ng-recaptcha/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221825585,"owners_count":16886987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular-recaptcha","captcha","google-recaptcha","ng-recaptcha","recaptcha-api"],"created_at":"2024-07-31T17:00:56.232Z","updated_at":"2024-10-30T15:31:28.281Z","avatar_url":"https://github.com/DethAriel.png","language":"TypeScript","funding_links":[],"categories":["Uncategorized","TypeScript"],"sub_categories":["Uncategorized"],"readme":"# Angular component for Google reCAPTCHA\n\n## ng-recaptcha [![npm version](https://badge.fury.io/js/ng-recaptcha.svg)](https://www.npmjs.com/package/ng-recaptcha)\n\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/dethariel/ng-recaptcha/master/LICENSE)\n[![Build Status](https://app.travis-ci.com/DethAriel/ng-recaptcha.svg?branch=master)](https://app.travis-ci.com/DethAriel/ng-recaptcha)\n[![Coverage Status](https://coveralls.io/repos/github/DethAriel/ng-recaptcha/badge.svg?branch=master)](https://coveralls.io/github/DethAriel/ng-recaptcha?branch=master)\n[![NPM downloads](https://img.shields.io/npm/dm/ng-recaptcha)](https://www.npmjs.com/package/ng-recaptcha)\n\nA simple, configurable, easy-to-start component for handling reCAPTCHA v2 and v3.\n\n## Table of contents\n\n1. [Installation](#installation)\n1. [Basic Usage](#example-basic)\n   - [reCAPTCHA v3 Usage](#example-basic-v3)\n   - [Playground](#playground)\n1. [Working with `@angular/forms`](#forms-ready)\n1. [API](#api)\n   - [Input Options](#api-options)\n   - [Events](#api-events)\n   - [Methods](#api-methods)\n1. [Angular version compatibility](#angular-versions)\n1. [Examples](#examples)\n   - [Configuring the component globally](#example-global-config)\n   - [Specifying a different language](#example-language)\n   - [Handling errors](#example-error-handling)\n   - [Loading the reCAPTCHA API by yourself](#example-preload-api)\n   - [Usage with `required` in forms](#example-forms)\n   - [Working with invisible reCAPTCHA](#example-invisible)\n   - [Resizing](#example-resizing)\n   - [SystemJS configuration](#example-systemjs)\n   - [Loading from a different location](#example-different-url)\n   - [Specifying nonce for Content-Security-Policy](#example-csp-nonce)\n   - [Listening for all actions with reCAPTCHA v3](#example-v3-all-actions)\n   - [Loading reCAPTCHA keys asynchronously](#async-config-load)\n   - [Hiding reCAPTCHA badge](#hide-recaptcha-badge)\n\n## \u003ca name=\"installation\"\u003e\u003c/a\u003eInstallation\n\nThe easiest way is to install through [yarn](https://yarnpkg.com/package/ng-recaptcha) or [npm](https://www.npmjs.com/package/ng-recaptcha):\n\n```sh\nyarn add ng-recaptcha\nnpm i ng-recaptcha --save\n```\n\n## \u003ca name=\"example-basic\"\u003e\u003c/a\u003eBasic Usage [(see in action)](https://dethariel.github.io/ng-recaptcha/)\n\nThe below applies to reCAPTCHA v2, for basic usage with reCAPTCHA v3 scroll down to [here](#example-basic-v3).\n\nTo start with, you need to import the `RecaptchaModule` (more on that [later](#modules)):\n\n```typescript\n// app.module.ts\nimport { RecaptchaModule } from \"ng-recaptcha\";\n// if you need forms support:\n// import { RecaptchaModule, RecaptchaFormsModule } from 'ng-recaptcha';\nimport { BrowserModule } from \"@angular/platform-browser\";\nimport { MyApp } from \"./app.component.ts\";\n\n@NgModule({\n  bootstrap: [MyApp],\n  declarations: [MyApp],\n  imports: [\n    BrowserModule,\n    RecaptchaModule,\n    // RecaptchaFormsModule, // if you need forms support\n  ],\n})\nexport class MyAppModule {}\n```\n\nOnce you have done that, the rest is simple:\n\n```typescript\n// app.component.ts\nimport { Component } from \"@angular/core\";\n\n@Component({\n  selector: \"my-app\",\n  template: `\u003cre-captcha (resolved)=\"resolved($event)\" siteKey=\"YOUR_SITE_KEY\"\u003e\u003c/re-captcha\u003e`,\n})\nexport class MyApp {\n  resolved(captchaResponse: string) {\n    console.log(`Resolved captcha with response: ${captchaResponse}`);\n  }\n}\n```\n\n```typescript\n// main.ts\nimport { platformBrowserDynamic } from \"@angular/platform-browser-dynamic\";\nimport { MyAppModule } from \"./app.module.ts\";\n\nplatformBrowserDynamic().bootstrapModule(MyAppModule);\n```\n\n### \u003ca name=\"example-basic-v3\"\u003e\u003c/a\u003ereCAPTCHA v3 Usage [(see in action)](https://dethariel.github.io/ng-recaptcha/v3)\n\n[reCAPTCHA v3](https://developers.google.com/recaptcha/docs/v3) introduces a different way of bot protection. To work with v3 APIs, `ng-recaptcha` provides a service (as opposed to a component). To start with, you need to import the `RecaptchaV3Module` and provide your reCAPTCHA v3 site key using `RECAPTCHA_V3_SITE_KEY` injection token:\n\n```ts\nimport { BrowserModule } from \"@angular/platform-browser\";\nimport { RECAPTCHA_V3_SITE_KEY, RecaptchaV3Module } from \"ng-recaptcha\";\n\nimport { MyApp } from \"./app.component.ts\";\n\n@NgModule({\n  bootstrap: [MyApp],\n  declarations: [MyApp],\n  imports: [BrowserModule, RecaptchaV3Module],\n  providers: [{ provide: RECAPTCHA_V3_SITE_KEY, useValue: \"\u003cYOUR_SITE_KEY\u003e\" }],\n})\nexport class MyAppModule {}\n```\n\nIn order to execute a reCAPTCHA v3 action, import the `ReCaptchaV3Service` into your desired component:\n\n```ts\nimport { ReCaptchaV3Service } from 'ng-recaptcha';\n\n@Component({\n  selector: 'recaptcha-demo',\n  template: `\n    \u003cbutton (click)=\"executeImportantAction()\"\u003eImportant action\u003c/button\u003e\n  `,\n})\nexport class RecaptchaV3DemoComponent {\n  constructor(\n    private recaptchaV3Service: ReCaptchaV3Service,\n  ) {\n  }\n\n  public executeImportantAction(): void {\n    this.recaptchaV3Service.execute('importantAction')\n      .subscribe((token) =\u003e this.handleToken(token));\n  }\n```\n\nAs always with subscriptions, please don't forget to **unsubscribe**.\n\n❗️ **Important note**: If your site uses both v2 and v3, then you should _always_ provide `RECAPTCHA_V3_SITE_KEY` (even in modules that only rely on v2 functionality). This will prevent bugs in your code by allowing `ng-recaptcha` to follow reCAPTCHA development guidelines properly ([this one](https://developers.google.com/recaptcha/docs/faq#can-i-run-recaptcha-v2-and-v3-on-the-same-page) in particular).\n\nA more advanced v3 usage scenario includes listening to all actions and their respectively emitted tokens. This is covered [later on this page](#example-v3-all-actions).\n\n### \u003ca name=\"playground\"\u003e\u003c/a\u003ePlayground\n\nYou can also play with [this Stackblitz demo](https://stackblitz.com/edit/ng-recaptcha-example) to get a feel of how this component can be used.\n\n## \u003ca name=\"forms-ready\"\u003e\u003c/a\u003eWorking with `@angular/forms`\n\nThere are two modules available for you:\n\n```typescript\nimport { RecaptchaModule, RecaptchaFormsModule } from \"ng-recaptcha\";\n```\n\nIf you want your `\u003cre-captcha\u003e` element to work correctly with `[(ngModel)]` directive,\nyou need to import the `RecaptchaFormsModule` into your application module (pretty much\nlike with Angular own `'@angular/forms'` module).\n\n## \u003ca name=\"api\"\u003e\u003c/a\u003eAPI\n\n### \u003ca name=\"api-options\"\u003e\u003c/a\u003eInput Options\n\nThe component supports this options:\n\n- `siteKey`\n- `theme`\n- `type`\n- `size`\n- `tabIndex`\n- `badge`\n\nThey are all pretty well described either in the [reCAPTCHA docs](https://developers.google.com/recaptcha/docs/display), or in the [invisible reCAPTCHA docs](https://developers.google.com/recaptcha/docs/invisible),\nso I won't duplicate it here.\n\nOne additional option that component accepts is `errorMode`. You can learn more about it in the [Handling errors](#example-error-handling) section below.\n\nBesides specifying these options on the component itself, you can provide a global `\u003cre-captcha\u003e` configuration - see [Configuring the component globally](#example-global-config) section below.\n\n### \u003ca name=\"api-events\"\u003e\u003c/a\u003eEvents\n\n- `resolved(response: string)`. Occurs when the captcha resolution value changed.\n  When user resolves captcha, use `response` parameter to send to the server for verification.\n  This parameter is equivalent to calling [`grecaptcha.getResponse`](https://developers.google.com/recaptcha/docs/display#js_api).\n\n  If the captcha has expired prior to submitting its value to the server, the component\n  will reset the captcha, and trigger the `resolved` event with `response === null`.\n\n- `errored(errorDetails: RecaptchaErrorParameters)`. Occurs when reCAPTCHA encounters an error (usually a connectivity problem) **if and only if** `errorMode` input has been set to `\"handled\"`.\n  `errorDetails` is a simple propagation of any arguments that the original `error-callback` has provided, and is documented here for the purposes of completeness and future-proofing. This array will most often (if not always) be empty. A good strategy would be to rely on just the fact that this event got triggered, and show a message to your app's user telling them to retry.\n\n### \u003ca name=\"api-methods\"\u003e\u003c/a\u003eMethods\n\n- `reset()`. Performs a manual captcha reset. This method might be useful if your form\n  validation failed, and you need the user to re-enter the captcha.\n- `execute()`. Executes the invisible recaptcha. Does nothing if component's size is not set to \"invisible\". See [Invisible reCAPTCHA developers guide](https://developers.google.com/recaptcha/docs/invisible#js_api) for more information.\n\n## \u003ca name=\"angular-versions\"\u003e\u003c/a\u003eAngular version compatibility\n\n| `ng-recaptcha` version                                                           | Supported Angular versions                           |\n| -------------------------------------------------------------------------------- | ---------------------------------------------------- |\n| `13.x.x`                                                                         | `17.x.x`                                             |\n| `12.x.x`                                                                         | `16.x.x`                                             |\n| `11.x.x`                                                                         | `15.x.x`                                             |\n| `10.x.x`                                                                         | `14.x.x`                                             |\n| `9.x.x`                                                                          | `13.x.x`                                             |\n| `8.x.x`                                                                          | `12.x.x`                                             |\n| `7.x.x`                                                                          | `11.x.x`                                             |\n| ⬆️ Starting with `ng-recaptcha@7`, only one version of Angular will be supported |\n| `6.x.x`                                                                          | `6.x.x \\|\\| 7.x.x \\|\\| 8.x.x \\|\\| 9.x.x \\|\\| 10.x.x` |\n| `5.x.x`                                                                          | `6.x.x \\|\\| 7.x.x \\|\\| 8.x.x`                        |\n| `4.x.x`                                                                          | `6.x.x \\|\\| 7.x.x`                                   |\n| `3.x.x`                                                                          | `4.x.x \\|\\| 5.x.x`                                   |\n| `2.x.x`                                                                          | `2.x.x \\|\\| 4.x.x`                                   |\n| `1.x.x`                                                                          | `2.x.x`                                              |\n\n## \u003ca name=\"examples\"\u003e\u003c/a\u003eExamples\n\n### \u003ca name=\"example-global-config\"\u003e\u003c/a\u003eConfiguring the component globally [(see in action)](https://dethariel.github.io/ng-recaptcha/global-config)\n\nSome properties are global - including `siteKey`, `size`, and others. You can provide them at the module-level using the `RECAPTCHA_SETTINGS` provider:\n\n```typescript\nimport { RECAPTCHA_SETTINGS, RecaptchaSettings } from \"ng-recaptcha\";\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_SETTINGS,\n      useValue: { siteKey: \"\u003cYOUR_KEY\u003e\" } as RecaptchaSettings,\n    },\n  ],\n})\nexport class MyModule {}\n```\n\nGlobal properties can be overridden on a case-by-case basis - the values on the `\u003cre-captcha\u003e` component itself take precedence over global settings.\n\n### \u003ca name=\"example-language\"\u003e\u003c/a\u003eSpecifying a different language [(see in action)](https://dethariel.github.io/ng-recaptcha/basic?lang-fr)\n\n`\u003cre-captcha\u003e` supports various languages. By default recaptcha will guess the user's language itself\n(which is beyond the scope of this lib).\nBut you can override this behavior and provide a specific language to use by setting the `\"hl\"` search param in the `onBeforeLoad` hook.\nNote, that the language setting is **global**, and cannot be set on a per-captcha basis.\n\nA good way to synchronize reCAPTCHA language with the rest of your application is relying on `LOCALE_ID` value like so:\n\n```typescript\nimport { LOCALE_ID } from \"@angular/core\";\nimport { RECAPTCHA_LOADER_OPTIONS } from \"ng-recaptcha\";\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_LOADER_OPTIONS,\n      useFactory: (locale: string) =\u003e ({\n        onBeforeLoad(url) {\n          url.searchParams.set(\"hl\", locale);\n\n          return { url };\n        },\n      }),\n      deps: [LOCALE_ID],\n    },\n  ],\n})\nexport class MyModule {}\n```\n\nAlternatively, a specific language can be provided like so:\n\n```typescript\nimport { RECAPTCHA_LOADER_OPTIONS } from \"ng-recaptcha\";\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_LOADER_OPTIONS,\n      useValue: {\n        onBeforeLoad(url) {\n          url.searchParams.set(\"hl\", \"fr\"); // use French language\n\n          return { url };\n        },\n      },\n    },\n  ],\n})\nexport class MyModule {}\n```\n\nYou can find the list of supported languages in [reCAPTCHA docs](https://developers.google.com/recaptcha/docs/language).\n\n### \u003ca name=\"example-error-handling\"\u003e\u003c/a\u003eHandling errors\n\nSometimes reCAPTCHA encounters an error, which is usually a network connectivity problem. It cannot continue until connectivity is restored. By default, reCAPTCHA lets the user know that an error has happened (it's a built-in functionality of reCAPTCHA itself, and this lib is not in control of it). The downside of such behavior is that you, as a developer, don't get notified about this in any way. Opting into such notifications is easy, but comes at a cost of assuming responsibility for informing the user that they should retry. Here's how you would do this:\n\n```typescript\nimport { Component } from \"@angular/core\";\n\n@Component({\n  selector: \"my-app\",\n  template: `\u003cre-captcha (resolved)=\"resolved($event)\" (errored)=\"errored($event)\" errorMode=\"handled\"\u003e\u003c/re-captcha\u003e`,\n})\nexport class MyApp {\n  resolved(captchaResponse: string) {\n    console.log(`Resolved captcha with response: ${captchaResponse}`);\n  }\n\n  errored() {\n    console.warn(`reCAPTCHA error encountered`);\n  }\n}\n```\n\nYou can see this in action by navigating to either [basic example demo](https://dethariel.github.io/ng-recaptcha/basic) or [invisible demo](https://dethariel.github.io/ng-recaptcha/invisible) and trying to interact with reCAPTCHA after setting the network to \"Offline\".\n\nThe `errorMode` input has two possible values -- `\"handled\"` and `\"default\"`, with latter being the default as the name suggests. Not specifying `errorMode`, or setting it to anything other than `\"handled\"` will not invoke your `(errored)` callback, and will instead result in default reCAPTCHA functionality.\n\nThe `(errored)` callback will propagate all of the parameters that it receives from `grecaptcha['error-callback']` (which might be none) as an array.\n\n### \u003ca name=\"example-preload-api\"\u003e\u003c/a\u003eLoading the reCAPTCHA API by yourself [(see in action)](https://dethariel.github.io/ng-recaptcha/v8/preload-api)\n\nBy default, the component assumes that the reCAPTCHA API loading will be handled\nby the `RecaptchaLoaderService`. However, you can override that by providing your\ninstance of this service to the Angular DI.\n\nThe below code snippet is an example of how such a provider can be implemented.\n\n**TL;DR**: there should be an `Observable` that eventually resolves to a\n`grecaptcha`-compatible object (e.g. `grecaptcha` itself).\n\n```html\n\u003cscript src=\"https://www.google.com/recaptcha/api.js?render=explicit\u0026amp;onload=onloadCallback\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  // bootstrap the application once the reCAPTCHA api has loaded\n  function onloadCallback() {\n    System.import(\"app\").catch(function (err) {\n      console.error(err);\n    });\n  }\n\u003c/script\u003e\n```\n\n```typescript\nimport { RecaptchaLoaderService } from \"ng-recaptcha\";\n\n@Injectable()\nexport class PreloadedRecaptchaAPIService {\n  public ready: Observable\u003cReCaptchaV2.ReCaptcha\u003e;\n\n  constructor() {\n    let readySubject = new BehaviorSubject\u003cReCaptchaV2.ReCaptcha\u003e(grecaptcha);\n    this.ready = readySubject.asObservable();\n  }\n}\n\n@NgModule({\n  providers: [\n    {\n      provide: RecaptchaLoaderService,\n      useValue: new PreloadedRecaptchaAPIService(),\n    },\n  ],\n})\nexport class MyModule {}\n```\n\n### \u003ca name=\"example-forms\"\u003e\u003c/a\u003eUsage with `required` in forms [(see in action)](https://dethariel.github.io/ng-recaptcha/forms)\n\nIt's very easy to put `\u003cre-captcha\u003e` in an Angular form and have it `require`d - just\nadd the `required` attribute to the `\u003cre-captcha\u003e` element. Do not forget to import `RecaptchaFormsModule` from `'ng-recaptcha'`!\n\n```typescript\n@Component({\n  selector: \"my-form\",\n  template: ` \u003cform\u003e\n    \u003cre-captcha [(ngModel)]=\"formModel.captcha\" name=\"captcha\" required siteKey=\"YOUR_SITE_KEY\"\u003e\u003c/re-captcha\u003e\n  \u003c/form\u003e`,\n})\nexport class MyForm {\n  formModel = new MyFormModel();\n}\n```\n\nA similar approach can be taken for reactive forms:\n\n```typescript\n@Component({\n  selector: \"my-reactive-form\",\n  template: `\n    \u003cform [formGroup]=\"reactiveForm\"\u003e\n      \u003cre-captcha formControlName=\"recaptchaReactive\"\u003e\u003c/re-captcha\u003e\n      \u003cbutton [disabled]=\"reactiveForm.invalid\"\u003eSubmit\u003c/button\u003e\n    \u003c/form\u003e\n  `,\n})\nexport class MyReactiveForm {\n  reactiveForm: FormGroup;\n\n  ngOnInit() {\n    this.reactiveForm = new FormGroup({\n      recaptchaReactive: new FormControl(null, Validators.required),\n    });\n  }\n}\n```\n\n### \u003ca name=\"example-invisible\"\u003e\u003c/a\u003eWorking with invisible reCAPTCHA [(see in action)](https://dethariel.github.io/ng-recaptcha/invisible)\n\nWorking with [invisible reCAPTCHA](https://developers.google.com/recaptcha/docs/invisible) is almost the same as with regular one.\nFirst, you need to provide the right size:\n\n```html\n\u003cre-captcha size=\"invisible\" ...\u003e\u003c/re-captcha\u003e\n```\n\nYou will also need to invoke the [`\"execute()\"`](https://developers.google.com/recaptcha/docs/invisible#programmatic_execute) method manually. This can be done by either obtaining a reference to `RecaptchaComponent` via `@ViewChild()`, or by using inline template reference:\n\n```html\n\u003cre-captcha #captchaRef=\"reCaptcha\" ...\u003e\u003c/re-captcha\u003e\n...\n\u003cbutton (click)=\"captchaRef.execute()\"\u003eSubmit\u003c/button\u003e\n```\n\nNormally you would only submit a form when recaptcha response has been received. This can be achieved by reacting to `(resolved)` event and invoking submit logic when the captcha response is truthy (this will not try to submit the form when recaptcha response has expired). A sample implementation would look like this:\n\n```typescript\n@Component({\n  selector: \"my-form\",\n  template: ` \u003cform\u003e\n    \u003cre-captcha\n      #captchaRef=\"reCaptcha\"\n      siteKey=\"YOUR_SITE_KEY\"\n      size=\"invisible\"\n      (resolved)=\"$event \u0026\u0026 submit($event)\"\n    \u003e\u003c/re-captcha\u003e\n    \u003cbutton (click)=\"captchaRef.execute()\"\u003eSubmit\u003c/button\u003e\n  \u003c/form\u003e`,\n})\nexport class MyForm {\n  public submit(captchaResponse: string): void {\n    this.http.post({\n      captcha: captchaResponse,\n      /* ... */\n    });\n  }\n}\n```\n\n### \u003ca name=\"example-resizing\"\u003e\u003c/a\u003eResizing\n\nMaking reCAPTCHA responsive is sometimes necessary, especially when working with mobile devices. You can use css-transforms to achieve that as in [this StackOverflow answer](https://stackoverflow.com/a/29521983/2645305), which is also ell-described in [this blog post](https://geekgoddess.com/how-to-resize-the-google-nocaptcha-recaptcha/). You can also take a look at a [live example](https://stackblitz.com/edit/ng-recaptcha-example-uncvxq?file=src/app/app.component.html) of how this might be implemented. This boils down to\n\n```html\n\u003cdiv style=\"transform:scale(0.7);transform-origin:0;\"\u003e\n  \u003cre-captcha\u003e\u003c/re-captcha\u003e\n\u003c/div\u003e\n```\n\n### \u003ca name=\"example-systemjs\"\u003e\u003c/a\u003eSystemJS configuration\n\nTo configure the package to work with SystemJS, you would configure it approximately like that (assuming you've installed `ng-recaptcha` using `npm`):\n\n```javascript\n// SystemJS config file\n(function () {\n  System.config({\n    paths: {\n      \"npm:\": \"/node_modules/\",\n    },\n    map: {\n      \"ng-recaptcha\": \"npm:ng-recaptcha\",\n    },\n    packages: {\n      \"ng-recaptcha\": { main: \"./index.js\" },\n    },\n  });\n})();\n```\n\n### \u003ca name=\"example-different-url\"\u003e\u003c/a\u003eLoading from a different location\n\nSince `\"google.com\"` domain might be unavailable in some countries, reCAPTCHA core team has a solution for that - using `\"recaptcha.net\"` domain. You can configure the component to use that by using the `onBeforeLoad` hook of `RECAPTCHA_LOADER_OPTIONS`, for example:\n\n```javascript\nimport { RECAPTCHA_LOADER_OPTIONS } from \"ng-recaptcha\";\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_LOADER_OPTIONS,\n      useValue: {\n        onBeforeLoad(_url) {\n          return {\n            url: new URL(\"https://www.recaptcha.net/recaptcha/api.js\"), // use recaptcha.net script source for some of our users\n          };\n        },\n      },\n    },\n  ],\n})\nexport class MyModule {}\n```\n\n### \u003ca name=\"example-csp-nonce\"\u003e\u003c/a\u003eSpecifying nonce for Content-Security-Policy\n\nPer [reCAPTCHA FAQ on CSP](https://developers.google.com/recaptcha/docs/faq#im-using-content-security-policy-csp-on-my-website-how-can-i-configure-it-to-work-with-recaptcha), the recommended approach for that is to supply nonce to the script tag. This is possible by providing the nonce as part of the `onBeforeLoad` hook of `RECAPTCHA_LOADER_OPTIONS`, for example\n\n```javascript\nimport { RECAPTCHA_LOADER_OPTIONS } from \"ng-recaptcha\";\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_LOADER_OPTIONS,\n      useValue: {\n        onBeforeLoad(_url) {\n          return {\n            url,\n            nonce: \"\u003cYOUR_NONCE_VALUE\u003e\",\n          };\n        },\n      },\n    },\n  ],\n})\nexport class MyModule {}\n```\n\n### \u003ca name=\"example-v3-all-actions\"\u003e\u003c/a\u003eListening for all actions with reCAPTCHA v3\n\nMore often than not you will need to only get a reCAPTCHA token with the action the user is currently taking, and submit it to the backend at that time. However, having a single listener for all events will be desirable.\n\nThere is an `Observable` exactly for that purpose: `ReCaptchaV3Service.onExecute`. It emits a value every time a token is received from reCAPTCHA. The shape of payload it operates on is defined via `OnExecuteData` interface:\n\n```ts\ninterface OnExecuteData {\n  action: string;\n  token: string;\n}\n```\n\nwhere `action` is the name of the action that has been executed, and `token` is what reCAPTCHA v3 provided when executing that action.\n\nHere's how you would potentially set this up:\n\n```ts\nimport { OnExecuteData, ReCaptchaV3Service } from \"ng-recaptcha\";\n\n@Component({\n  selector: \"my-component\",\n  templateUrl: \"./v3-demo.component.html\",\n})\nexport class MyComponent implements OnInit, OnDestroy {\n  private subscription: Subscription;\n\n  constructor(private recaptchaV3Service: ReCaptchaV3Service) {}\n\n  public ngOnInit() {\n    this.subscription = this.recaptchaV3Service.onExecute.subscribe((data: OnExecuteData) =\u003e {\n      this.handleRecaptchaExecute(data.action, data.token);\n    });\n  }\n\n  public ngOnDestroy() {\n    if (this.subscription) {\n      this.subscription.unsubscribe();\n    }\n  }\n}\n```\n\nThere are a couple things to keep in mind:\n\n- `onExecute` will trigger for **all** actions. If you only need to bulk-process some actions, and not others - you will have to apply filtering yourself.\n- `onExecute` observable will provide you with all the events emitted **after** you have subscribed to it - it doesn't keep references to the previously emitted actions. So make sure you add such a subscription as early in your code as you feel is necessary.\n- `onExecute` does not emit anything for when a `grecaptcha` error occurs. Use `onExecuteError` Observable for that.\n\n### \u003ca name=\"async-config-load\"\u003e\u003c/a\u003eLoading reCAPTCHA keys asynchronously\n\nIf your use-case needs to load the reCAPTCHA v2/v3 key from the backend (as opposed to specifying it in-code during build time), the Angular-idiomatic way to do that is by relying on [`APP_INITIALIZER`](https://angular.io/api/core/APP_INITIALIZER). You can find an example of how this could look like below, and you can also consult the source code for the demo site.\n\n```ts\n// config.service.ts\nimport { Injectable } from \"@angular/core\";\n\n@Injectable({\n  providedIn: \"root\",\n})\nexport class ConfigService {\n  public recaptchaSiteKeyV2: string | null = null;\n  public recaptchaSiteKeyV3: string | null = null;\n\n  public async loadConfig(): Promise\u003cvoid\u003e {\n    const { siteKeyV2, siteKeyV3 } = await fetchConfig(/* some API call */);\n    this.recaptchaSiteKeyV2 = siteKeyV2;\n    this.recaptchaSiteKeyV3 = siteKeyV3;\n  }\n}\n\n// app.module.ts\nimport { APP_INITIALIZER, NgModule } from \"@angular/core\";\nimport { RECAPTCHA_SETTINGS, RecaptchaSettings, RECAPTCHA_V3_SITE_KEY } from \"ng-recaptcha\";\n\nimport { ConfigService } from \"./config.service\";\n\nfunction appLoadFactory(config: ConfigService) {\n  return () =\u003e config.loadConfig().then(() =\u003e console.log(`config resolved`, config));\n}\n\n@NgModule({\n  providers: [\n    {\n      provide: RECAPTCHA_V3_SITE_KEY,\n      useFactory: (config: ConfigService) =\u003e {\n        return config.recaptchaSiteKeyV3;\n      },\n      deps: [ConfigService],\n    },\n    {\n      provide: RECAPTCHA_SETTINGS,\n      useFactory: (config: ConfigService): RecaptchaSettings =\u003e {\n        return { siteKey: config.recaptchaSiteKeyV2 };\n      },\n      deps: [ConfigService],\n    },\n    {\n      provide: APP_INITIALIZER,\n      useFactory: appLoadFactory,\n      deps: [ConfigService],\n      multi: true,\n    },\n  ],\n})\nexport class AppModule {}\n```\n\n### \u003ca name=\"hide-recaptcha-badge\"\u003e\u003c/a\u003eHiding reCAPTCHA badge\n\nTo start with, this is not strictly under `ng-recaptcha` library control.\nHowever, there is a way of doing so (albeit subject to certain conditions).\nPlease refer to the [FAQ section of reCAPTCHA documentation](https://developers.google.com/recaptcha/docs/faq#id-like-to-hide-the-recaptcha-badge.-what-is-allowed) to get an idea of what you're required to do.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDethAriel%2Fng-recaptcha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDethAriel%2Fng-recaptcha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDethAriel%2Fng-recaptcha/lists"}