react-turnstile icon indicating copy to clipboard operation
react-turnstile copied to clipboard

Using with Remix: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Open biot023 opened this issue 1 year ago • 3 comments

Hello -- I'm trying to use the Turnstile component in a Remix app, like so:

import React from 'react';
import { Form } from "@remix-run/react";
import Turnstile, { useTurnstile } from "react-turnstile";

export default function Contact() {
  const turnstile = useTurnstile();

  return (
    <div>
      <h1>Contact me</h1>
      <Form method="post">
        <legend>Please enter message details</legend>
        <p>
          <input type="email" name="email" class="bg-transparent border-2 border-solid border-slate-50 rounded-sm"/>
        </p>
        <p>
          <textarea name="message" class="bg-transparent border-2 border-solid border-slate-50 rounded-sm"></textarea>
        </p>
        <Turnstile
          sitekey="1x00000000000000000000AA"
        />
        <button type="submit">Send message</button>
      </Form>
    </div>
  );
}

However, when I try to browse to this route, I get this error:

[ERROR] Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. Check your code at contact.tsx:19.

Line 19, that it mentions in the error, is where the Turnstile component is declared.

Is this something anyone else has come across? And can they offer any advice, if they have? Thank you, Doug.

biot023 avatar Mar 13 '24 15:03 biot023

Have the same problem. @biot023 Did you managed it?

Yaroslavpnts avatar Jul 25 '24 08:07 Yaroslavpnts

I worked around this by letting the Turnstile component only render on the client via ClientOnly from https://sergiodxa.github.io/remix-utils/#md:clientonly

emqMalte avatar Aug 03 '24 15:08 emqMalte

You need to render only on the client. With ClientOnly as emqMalte said, or with useEffect:

export default function ComponentWithTurnstile() {
  const [isClient, setIsClient] = useState(false);
  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    ...
    {isClient && <Turnstile ... />}
  )
}

dmm9 avatar Aug 11 '24 01:08 dmm9