Search code examples
reactjsastrojshcaptcha

HCaptcha event functions not triggering in AstroJS


This is index.astro file:

---
import HCaptcha from "@hcaptcha/react-hcaptcha";

function handleVerificationSuccess(token, ekey) {
  console.log("Token:", token);
  console.log("Ekey:", ekey);
}
---

<!doctype html>
<html lang="sr">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div>
      <HCaptcha
        client:load
        sitekey={import.meta.env.PUBLIC_MY_SITE_KEY}
        onVerify={(token, ekey) => handleVerificationSuccess(token, ekey)}
        onOpen={() => console.log("it's open")}
      />
    </div>
  </body>
</html>

In this code, onVerify never triggers, and the same happens with onOpen and any other event.

I tried using this same code in the React environment, without Astro, and it works, so I assume Astro is the problem, for some reason.

I tried creating a new JSX component, called Verification, and putting HCaptcha and handleVerificationSuccess function inside the same JSX file, but that didn't work as well, and I got the same results.

I'm out of ideas, and I'm not sure what I'm doing wrong.

Developer tools is giving me this warning, not sure if it's related:

Partitioned cookie or storage access was provided to https://newassets.hcaptcha.com...... because it is loaded in the third-party context and dynamic state partitioning is enabled.

Some cookies are misusing the recommended “SameSite“ attribute

Cookie “__cflb” has been rejected because it is in a cross-site context and its “SameSite” is “Lax” or “Strict”. https://api.hcaptcha.com/getcaptcha/my_sitekey

Cookie “__cflb” has been rejected because it is in a cross-site context and its “SameSite” is “Lax” or “Strict”. https://api.hcaptcha.com/checkcaptcha/my_site_key/long_array_of_numbers_and_letters

Update #1

Tried creating verify.jsx and adding HCaptcha component and necessary logic there.

index.astro

---
import Verification from "../components/verification.jsx";
---

<!doctype html>
<html lang="sr">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <div>
      <Verification client:load />
    </div>
  </body>
</html>

verification.jsx

import React from 'react';
import HCaptcha from "@hcaptcha/react-hcaptcha";

const Verification = () => {

  function handleVerificationSuccess(token, ekey) {
    console.log("Token:", token);
    console.log("Ekey:", ekey);
  }

  return (
      <div>
       <HCaptcha
       sitekey={import.meta.env.PUBLIC_MY_SITE_KEY}
       onVerify={(token, ekey) => handleVerificationSuccess(token, ekey)}
       onOpen={() => console.log("it's open")}
     />
      </div>
  );
};

export default Verification;

Same issue occurs, onVerify and onOpen evens are never triggered.

Update #2

I had logs hidden in DevTools, moving everything to verification.jsx worked.


Solution

  • From Astro docs:

    You can pass a function as a prop to a framework component, but it only works during server rendering. If you try to use the function in a hydrated component (for example, as an event handler), an error will occur.

    This is because functions can’t be serialized (transferred from the server to the client) by Astro.

    That's why the handleVerificationSuccess function doesn't work. You need to write your own React component that wraps HCaptcha and includes handleVerificationSuccess.

    If you remember that Astro components are only executed on the server, while React components are (with client:only only) executed on the client, this actually makes sense.