npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@htmlbricks/hb-captcha-google-recaptcha-v2-invisible

v0.73.7

Published

Loads the Google reCAPTCHA v2 invisible SDK, renders the widget with your `api_key`, and exposes `grecaptcha.execute()` / reset when the `get` attribute changes after render. Dispatches `googleRecaptchaRendered` once mounted and `googleRecaptchaV2Response

Readme

hb-captcha-google-recaptcha-v2-invisible

Category: utilities · Tags: utilities, security

Summary

Custom element that loads Google’s reCAPTCHA v2 explicit API, mounts an invisible widget in the document light DOM, runs execution when the SDK is ready, and surfaces the verification token and render lifecycle through custom events.

What it does

  • Injects https://www.google.com/recaptcha/api.js?render=explicit (async/defer) into document.head with a stable script id (recaptchav2-sdk), if not already present.
  • Ensures a host div exists on document.body with id recaptchav2-element, data-size="invisible", then calls grecaptcha.render() with your site key (api_key) and a callback that dispatches the response event.
  • After a successful render, dispatches googleRecaptchaRendered, then from onMount’s load path calls grecaptcha.execute() once the widget is ready.
  • Polls (starting after 1s, then 2s retries) until window.grecaptcha is available and api_key is set before rendering.
  • On teardown, removes that script node and body div, clears the polling timer, and assigns window.grecaptcha to undefined.

How it renders

  • Shadow root: Forwards Bulma + component SCSS (styles/bulma.scss, styles/webcomponent.scss); there is no visible captcha UI inside the shadow tree.
  • Light DOM / Google widget: The actual reCAPTCHA widget is attached via the recaptchav2-element div appended to document.body (not inside the custom element). Integrators should assume global script injection and a body-level placeholder, not a child of <hb-captcha-google-recaptcha-v2-invisible>.

Logic: site key, token, and get

  • Site key: The api_key prop is passed to grecaptcha.render(..., { sitekey: api_key, callback }).
  • Token: When Google invokes the callback, the component dispatches googleRecaptchaV2Response with detail.response (string). The implementation also toggles internal state so a later programmatic run can reset() then execute() if a response was already produced (execCaptcha()).
  • get: An $effect runs when reactive dependencies change (including get). After the widget has rendered and an internal “ready” latch is set, if get !== null it calls execCaptcha() again (execute, or reset+execute if a response was already received). So null suppresses that path; undefined and other non-null values still satisfy get !== null once the latch is set—align testing with that condition, not only “attribute changed”.

Attributes / props (Component, snake_case)

| Name | Type (authoring) | Role | | --- | --- | --- | | api_key | string (optional) | reCAPTCHA site key passed to grecaptcha.render as sitekey. | | get | optional (typed any) | Participates in the post-render $effect / execCaptcha() flow; see above (get !== null). |

HTML consumers should follow your platform’s rules for string attributes (e.g. booleans as yes / no where applicable).

Events (CustomEvent)

| Event | detail (TypeScript) | | --- | --- | | googleRecaptchaV2Response | { response: string } — verification token from the callback. | | googleRecaptchaRendered | { render: true } — fired once after grecaptcha.render completes in this component. |

Styling

  • Bulma theme tokens are forwarded onto :host even though the captcha UI is not in the shadow tree (extra/docs.ts).
  • Documented CSS custom properties for catalog/style setup: --bulma-link, --bulma-text (colors; defaults follow the forwarded Bulma theme).

Parts and slots

  • ::part: none (cssParts is empty).
  • Slots: none (htmlSlots is empty).

Typings

Authoring types live in types/webcomponent.type.d.ts:

  • Component: api_key?, get?
  • Events: googleRecaptchaV2Response{ response: string }; googleRecaptchaRendered{ render: true }

Example

Google’s public test site key for v2 (always passes in test mode); replace with your production key.

<hb-captcha-google-recaptcha-v2-invisible api_key="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"></hb-captcha-google-recaptcha-v2-invisible>
const el = document.querySelector("hb-captcha-google-recaptcha-v2-invisible");

el.addEventListener("googleRecaptchaRendered", (e) => {
  console.log("rendered", e.detail); // { render: true }
});

el.addEventListener("googleRecaptchaV2Response", (e) => {
  console.log("token", e.detail.response);
});

Integrator note: CSP, domain allowlisting, and Google’s key/domain configuration apply outside this component.