Interface
interface TurnstileInstance extends Omit<Turnstile.Turnstile, 'ready'> {
render: () => string | null | undefined
execute: () => void
reset: () => void
remove: () => void
getResponse: () => string | undefined
getResponsePromise: (timeout?: number, retry?: number) => Promise<string>
isExpired: () => boolean
}
Usage
Access these methods using React refs:
import { useRef } from 'react'
import Turnstile from '@marsidev/react-turnstile'
import type { TurnstileInstance } from '@marsidev/react-turnstile'
function MyComponent() {
const turnstileRef = useRef<TurnstileInstance>(null)
const handleReset = () => {
turnstileRef.current?.reset()
}
return <Turnstile ref={turnstileRef} siteKey="your-site-key" />
}
Methods
render
render(): string | null | undefined
Explicitly renders the Turnstile widget.
Returns: The rendered widget ID, or undefined if rendering fails.
Example:
const widgetId = turnstileRef.current?.render()
if (widgetId) {
console.log('Widget rendered with ID:', widgetId)
}
execute
Renders a widget when options.execution is set to 'execute'. This method should be called after the .render() method. If options.execution is set to 'render', this method has no effect.
Example:
// First render the widget
turnstileRef.current?.render()
// Then execute when ready (for invisible widgets)
turnstileRef.current?.execute()
reset
Resets the Turnstile widget to its initial state. Useful for allowing users to retry after an error or when form submission fails.
Example:
const handleFormError = () => {
// Reset the widget so user can try again
turnstileRef.current?.reset()
}
remove
Fully removes the Turnstile widget from the DOM. Use this for cleanup or when dynamically showing/hiding the widget.
Example:
const handleCleanup = () => {
turnstileRef.current?.remove()
}
getResponse
getResponse(): string | undefined
Gets the current token response from the Turnstile widget.
Returns: The token string if available, or undefined if the widget hasn’t been solved yet.
Example:
const handleSubmit = () => {
const token = turnstileRef.current?.getResponse()
if (token) {
// Send token to your server for validation
validateToken(token)
} else {
console.error('No token available')
}
}
getResponsePromise
getResponsePromise(timeout?: number, retry?: number): Promise<string>
Gets the response of a Turnstile widget as a promise. It waits until the widget is rendered and solved.
Timeout in milliseconds. Defaults to 30000 (30 seconds).
Retry interval in milliseconds. Defaults to 250ms.
Returns: A promise that resolves with the token string.
Throws: Error if the widget times out or fails to get a response.
Example:
const handleSubmit = async () => {
try {
// Wait up to 30 seconds for the token
const token = await turnstileRef.current?.getResponsePromise()
// Validate on your server
await fetch('/api/verify', {
method: 'POST',
body: JSON.stringify({ token })
})
} catch (error) {
console.error('Failed to get turnstile token:', error)
}
}
Custom timeout example:
// Wait up to 10 seconds, checking every 100ms
const token = await turnstileRef.current?.getResponsePromise(10000, 100)
isExpired
Checks whether the token returned by the widget is expired.
Returns: true if the token is expired, false otherwise.
Example:
const handleSubmit = () => {
const expired = turnstileRef.current?.isExpired()
if (expired) {
console.log('Token expired, resetting widget')
turnstileRef.current?.reset()
return
}
const token = turnstileRef.current?.getResponse()
// Proceed with token validation
}
Common Patterns
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
try {
const token = await turnstileRef.current?.getResponsePromise()
const response = await fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token, ...formData })
})
if (!response.ok) {
// Reset on error
turnstileRef.current?.reset()
}
} catch (error) {
console.error('Turnstile error:', error)
}
}
function InvisibleCaptcha() {
const turnstileRef = useRef<TurnstileInstance>(null)
const handleButtonClick = async () => {
// Render invisible widget
turnstileRef.current?.render()
// Execute the challenge
turnstileRef.current?.execute()
// Wait for token
const token = await turnstileRef.current?.getResponsePromise()
// Use token...
}
return (
<>
<button onClick={handleButtonClick}>Submit</button>
<Turnstile
ref={turnstileRef}
siteKey="your-site-key"
options={{ execution: 'execute', size: 'invisible' }}
/>
</>
)
}