Multiple widgets

You can have multiple widgets on the same page, you just need to use different <Turnstile /> components.

For semantic purposes, it's recommended to use a unique id for each widget. Otherwise, you will have more then one container with the same id in the DOM.

import { Turnstile } from '@marsidev/react-turnstile'

export default function Widgets() {
  return (
    <>
      <Turnstile id='widget-1' siteKey='1x00000000000000000000AA' />
      <Turnstile id='widget-2' siteKey='1x00000000000000000000AA' />
    </>
  )
}

You can use multiple useRef to interact with each widget:

import { Turnstile } from '@marsidev/react-turnstile'

export default function Widgets() {
  const widget1 = React.useRef()
  const widget2 = React.useRef()

  return (
    <>
      <Turnstile ref={widget1} id='widget-1' siteKey='1x00000000000000000000AA' />
      <Turnstile ref={widget2} id='widget-2' siteKey='1x00000000000000000000AA' />

      <button onClick={() => alert(widget1.current?.getResponse())}>
        Get widget 1 response
      </button>

      <button onClick={() => alert(widget2.current?.getResponse())}>
        Get widget 2 response
      </button>
    </>
  )
}

You even can add multiple widgets while manually injecting the Cloudflare script. The following shows how to do it in Next.js 13:

import { DEFAULT_SCRIPT_ID, SCRIPT_URL, Turnstile } from '@marsidev/react-turnstile'
import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script id={DEFAULT_SCRIPT_ID} src={SCRIPT_URL} strategy="beforeInteractive" />
      <Turnstile id='widget-1' injectScript={false} siteKey='1x00000000000000000000AA' />
      <Turnstile id='widget-2' injectScript={false} siteKey='1x00000000000000000000AA' />
    </>
  )
}

This is not the only way to do it. You can also manually inject the script by using a native <script /> tag in your HTML entry file or inside an useEffect hook with the document.body.appendChild function. The key is to make sure that the script is loaded with the src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit".