Replies: 3 comments 1 reply
-
no it doesn't help |
Beta Was this translation helpful? Give feedback.
-
In case anyone else stumbles across this. I solved this with a The Note, the implementation allows this hook to function Render() {
const recaptcha = useGoogleRecaptcha({
siteKey: 'YOUR_SITE_KEY',
action: 'login',
})
const onSubmit = async (e) => {
e.prevenDefault()
const token = await recaptcha.execute()
const body = new FormData(e.target)
body.set('g-recaptcha-response', token)
// update and submit form
}
return (
<form onSubmit={onSubmit}>
<button type='submit' disabled={!recaptcha.ready}>Submit</button>
</form>
)
} Implementation import { useCallback, useEffect, useState } from 'react'
// define a typescript definition for grecaptcha enterprise ready and enterprise.execute
// https://developers.google.com/recaptcha/docs/enterprise/verify
// https://developers.google.com/recaptcha/docs/enterprise/clientapi#execute
declare global {
interface Window {
grecaptcha: {
enterprise: {
ready: (cb: () => void) => void
execute: (
siteKey: string,
options: { action: string },
) => Promise<string>
}
}
}
}
export type useRecaptchaParams = {
siteKey?: string
action?: string
}
/**
* useGoogleRecaptcha is a hook that loads the google recaptcha script into the head tag
* this hook provides a set of utilities for binding a recaptcha token to a user action
* if the siteKey is not provided these functions are considered noop
*/
export function useGoogleRecaptcha(params: useRecaptchaParams) {
const [ready, setReady] = useState(false)
// load the google recaptcha script into the head tag
// if the siteKey is not provided, the recaptcha will not be loaded but
// will be marked as ready
useEffect(() => {
// do nothing if the siteKey is not provided
if (!params.siteKey) {
setReady(true)
return
}
// inject the google recaptcha script into the head tag in a useEffect hook
const scriptURL = new URL('https://www.google.com/recaptcha/enterprise.js')
scriptURL.searchParams.set('render', params.siteKey || '')
const script = document.createElement('script')
script.src = scriptURL.toString()
script.async = true
script.defer = true
script.onload = () => {
console.debug('recaptcha loaded')
window.grecaptcha.enterprise.ready(() => {
setReady(true)
})
}
document.head.appendChild(script)
return () => {
setReady(false)
console.debug('recaptcha unloaded')
document.head.removeChild(script)
}
}, [params.siteKey])
// generate a recaptcha token when a user action is executed
// return an empty string if the siteKey is not provided
const execute = useCallback(async () => {
if (!params.siteKey) {
return ''
}
if (!ready) {
throw new Error('recaptcha was not loaded properly')
}
return await window.grecaptcha.enterprise.execute(params.siteKey || '', {
action: params.action || '',
})
}, [params.siteKey, params.action, ready])
return { ready, execute }
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi, I have a problem with Remix 2 and React 18 using library
https://github.com/dozoisch/react-google-recaptcha
Looks like it just fails to render in a new remix/react version but no errors are thrown. Actually nothing happens.
But it works as a charm in Remix 1 and React 17.
Any ideas what can it be? I've tried manual injecting of a recaptcha script to the header and the end of the body but it comes with hydration errors.
Remix 2.3.1:
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-google-recaptcha": "^3.1.0",
recaptcha requires types to be imported
"@types/react-google-recaptcha": "^2.1.8",
import { ReCAPTCHA } from "react-google-recaptcha";
if imported like that fails:
import ReCAPTCHA from "react-google-recaptcha";
Looks like it doesn't even injects google recaptcha script element to DOM.
Inited like <ReCAPTCHA sitekey={ loaderData.rkey! } theme="dark" />
Beta Was this translation helpful? Give feedback.
All reactions