### Install nextjs-turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Install the package using npm. This is the first step to integrate Turnstile into your Next.js project.
```bash
npm install nextjs-turnstile
```
--------------------------------
### Client Utility: Load Turnstile Script
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of asynchronously loading the Turnstile script. This is often done once at the application level.
```javascript
import { loadTurnstileScript, isTurnstileLoaded } from 'nextjs-turnstile';
async function initializeTurnstile() {
if (!isTurnstileLoaded()) {
try {
await loadTurnstileScript();
console.log('Turnstile script loaded successfully.');
} catch (error) {
console.error('Failed to load Turnstile script:', error);
}
} else {
console.log('Turnstile script already loaded.');
}
}
// Call this function when your app initializes
// initializeTurnstile();
```
--------------------------------
### Turnstile Component Example
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of how to integrate the Turnstile component into a Next.js form. Includes handling the token on success.
```jsx
import Turnstile from 'nextjs-turnstile';
function MyForm() {
const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const token = formData.get('cf-turnstile-response');
// Verify token on the server
const response = await fetch('/api/verify-turnstile', {
method: 'POST',
body: JSON.stringify({ token }),
});
if (response.ok) {
alert('Form submitted successfully!');
} else {
alert('CAPTCHA verification failed.');
}
};
return (
);
}
```
--------------------------------
### Client Utility: Execute Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of programmatically executing the Turnstile challenge using its reference. This can be used to trigger verification on demand.
```javascript
import { executeTurnstile, TurnstileRef } from 'nextjs-turnstile';
// Assuming you have a ref to the Turnstile component:
// const turnstileRef = React.useRef(null);
// To execute the widget:
// executeTurnstile(turnstileRef.current);
```
--------------------------------
### Deferred Turnstile Execution Example
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
This example demonstrates how to defer the Turnstile challenge execution until a user clicks the submit button. The form submission is then handled asynchronously after a token is received.
```tsx
function DeferredForm() {
const turnstileRef = useRef(null);
const [token, setToken] = useState(null);
const handleSubmit = async () => {
// Start the challenge
turnstileRef.current?.execute();
// Wait for token via onSuccess callback
// The form will submit once token is set
};
useEffect(() => {
if (token) {
// Token received, submit the form
submitForm(token);
}
}, [token]);
return (
);
}
```
--------------------------------
### Server-Side Verification API Route Example
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of a Next.js API route to handle Turnstile token verification. It uses the verifyTurnstile utility function.
```typescript
import type { NextApiRequest, NextApiResponse } from 'next';
import { verifyTurnstile } from 'nextjs-turnstile/server';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method === 'POST') {
const { token } = req.body;
if (!token) {
return res.status(400).json({ success: false, message: 'Token is required' });
}
try {
const isVerified = await verifyTurnstile(token, {
secretKey: process.env.CLOUDFLARE_SECRET_KEY,
});
if (isVerified) {
res.status(200).json({ success: true, message: 'CAPTCHA verified successfully' });
} else {
res.status(400).json({ success: false, message: 'CAPTCHA verification failed' });
}
} catch (error) {
console.error('Turnstile verification error:', error);
res.status(500).json({ success: false, message: 'Internal server error' });
}
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
```
--------------------------------
### VerifyTurnstile Example
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Demonstrates how to call `verifyTurnstile()` with custom options for secret key, action, hostname, and timeout. Ensure the secret key is securely loaded from environment variables.
```typescript
await verifyTurnstile(token, {
secretKey: process.env.TURNSTILE_SECRET_KEY,
action: "contact_form",
hostname: "example.com",
timeout: 5000,
});
```
--------------------------------
### Minimal Turnstile Form Example
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
A basic Next.js client component demonstrating how to integrate the Turnstile component into a form and handle token submission.
```tsx
"use client";
import { Turnstile } from "nextjs-turnstile";
import { useState } from "react";
export default function Form() {
const [token, setToken] = useState(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!token) return;
const res = await fetch("/api/verify", {
method: "POST",
body: JSON.stringify({ token }),
});
if (res.ok) {
console.log("Success!");
}
};
return (
);
}
```
--------------------------------
### WidgetRef Usage Examples
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Demonstrates how to use WidgetRef with client utility functions like resetTurnstile, accepting string IDs, numeric IDs, or DOM elements.
```typescript
resetTurnstile("widget-0");
resetTurnstile(0);
resetTurnstile(document.querySelector('#my-widget'));
```
--------------------------------
### Complete Turnstile Widget Initialization and Usage
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
An example showing how to load the Turnstile script, render a widget with a site key and callback, and handle form submission with token validation and retrieval.
```javascript
import {
loadTurnstileScript,
isTurnstileLoaded,
renderTurnstile,
getTurnstileResponse,
resetTurnstile,
isTokenExpired,
} from "nextjs-turnstile";
async function initWidget() {
// Load script
await loadTurnstileScript();
// Verify it's loaded
if (!isTurnstileLoaded()) {
console.error("Turnstile failed to load");
return;
}
// Render widget
const widgetId = await renderTurnstile('#my-widget', {
sitekey: 'your-site-key',
callback: (token) => console.log('Success:', token),
});
if (!widgetId) {
console.error("Widget render failed");
return;
}
// Use the widget
const handleSubmit = () => {
if (isTokenExpired(widgetId)) {
alert("CAPTCHA expired. Resetting...");
resetTurnstile(widgetId);
return;
}
const token = getTurnstileResponse(widgetId);
if (token) {
console.log("Submitting with token:", token);
// Submit form
}
};
return { widgetId, handleSubmit };
}
```
--------------------------------
### Client Utility: Get Turnstile Response
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of retrieving the Turnstile token from a widget using its reference. Returns the token or null if unavailable.
```javascript
import { getTurnstileResponse, TurnstileRef } from 'nextjs-turnstile';
// Assuming you have a ref to the Turnstile component:
// const turnstileRef = React.useRef(null);
// To get the response token:
// const token = getTurnstileResponse(turnstileRef.current);
// console.log('Current token:', token);
```
--------------------------------
### Client Utility: Render Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of manually rendering a Turnstile widget into a specific DOM element. Returns the widget ID upon success.
```javascript
import { renderTurnstile } from 'nextjs-turnstile';
async function setupTurnstileWidget() {
const containerElement = document.getElementById('turnstile-container');
if (containerElement) {
try {
const widgetId = await renderTurnstile(containerElement, {
siteKey: 'YOUR_CLOUDFLARE_SITE_KEY',
theme: 'dark',
});
console.log('Turnstile widget rendered with ID:', widgetId);
} catch (error) {
console.error('Failed to render Turnstile widget:', error);
}
}
}
// Call this function after the DOM is ready
// setupTurnstileWidget();
```
--------------------------------
### Render Turnstile Widget with Site Key
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Example of rendering the Turnstile component. It automatically uses the NEXT_PUBLIC_TURNSTILE_SITE_KEY environment variable if available, or accepts an explicit siteKey prop.
```tsx
```
```tsx
// Or override with prop
```
--------------------------------
### Client Utility: Reset Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of resetting a Turnstile widget programmatically using its reference. This is useful for clearing a previous response.
```javascript
import { resetTurnstile, TurnstileRef } from 'nextjs-turnstile';
// Assuming you have a ref to the Turnstile component:
// const turnstileRef = React.useRef(null);
// To reset the widget:
// resetTurnstile(turnstileRef.current);
```
--------------------------------
### Minimal Turnstile API Route for Verification
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
An example Next.js API route handler for verifying the Turnstile token received from the client.
```typescript
import { verifyTurnstile } from "nextjs-turnstile";
export async function POST(req: Request) {
const { token } = await req.json();
const ok = await verifyTurnstile(token);
return Response.json({ success: ok }, { status: ok ? 200 : 400 });
}
```
--------------------------------
### Reset Turnstile Widget Examples
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Demonstrates how to reset a Turnstile widget using different reference types: string ID, number ID, or DOM element.
```javascript
// By ID
resetTurnstile('widget-0');
```
```javascript
// By number
resetTurnstile(0);
```
```javascript
// By DOM element
resetTurnstile(document.getElementById('my-widget'));
```
```javascript
// By querySelector (if supported)
resetTurnstile(document.querySelector('#my-widget'));
```
--------------------------------
### Standard Turnstile Form Configuration
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
This snippet shows the basic setup for the Turnstile component, utilizing default configurations for most behaviors. It's recommended for most standard form integrations.
```tsx
console.error("Turnstile error")}
/>
```
--------------------------------
### Turnstile Component with Callbacks
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Example demonstrating how to use Turnstile callbacks for handling successful responses, errors, and token expiration. The `onSuccess` callback receives the verification token.
```tsx
import Turnstile from 'nextjs-turnstile';
function MyForm() {
const handleSuccess = (token: string) => {
console.log('Turnstile Success:', token);
// Submit the token to your backend for verification
};
const handleError = (errorCode?: string) => {
console.error('Turnstile Error:', errorCode);
// Handle error, e.g., show a message to the user
};
const handleExpire = () => {
console.log('Turnstile Token Expired');
// Handle token expiration, e.g., prompt user to retry
};
return (
);
}
```
--------------------------------
### Turnstile Component with Customization
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Example showing how to customize the Turnstile widget's appearance and behavior using various props like `theme`, `size`, `appearance`, and `language`.
```tsx
import Turnstile from 'nextjs-turnstile';
function MyForm() {
return (
);
}
```
--------------------------------
### Verify Turnstile Token on Server (App Router)
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Implement server-side verification of the Turnstile token using the `verifyTurnstile` utility. This example demonstrates how to handle a POST request, extract the token, verify it, and respond accordingly.
```ts
// app/api/contact/route.ts (App Router)
import { verifyTurnstile } from "nextjs-turnstile";
export async function POST(request: Request) {
const { token } = await request.json();
const isValid = await verifyTurnstile(token);
if (!isValid) {
return Response.json(
{ error: "CAPTCHA verification failed" },
{ status: 400 }
);
}
// Token is valid, continue with your logic...
return Response.json({ success: true });
}
```
--------------------------------
### Execute Turnstile Challenge
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Starts the Turnstile challenge imperatively. This method only works when the `execution` prop is set to "execute". It is ignored if `execution` is set to "render".
```typescript
// Later, trigger the challenge:
ref.current?.execute();
```
--------------------------------
### executeTurnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Executes the challenge for a widget configured with `execution="execute"` mode. This function starts the Turnstile challenge and is typically called in response to a user action, like a button click. It does nothing if called on a widget configured for `execution="render"`.
```APIDOC
## executeTurnstile
### Description
Executes the challenge for a widget with `execution="execute"` mode. Starts the challenge and is typically called in response to a user action. Does nothing if called on a widget with `execution="render"`.
### Method
```ts
function executeTurnstile(widgetRef: WidgetRef): void
```
### Parameters
#### Path Parameters
- **widgetRef** (`string | number | HTMLElement`) - Required - Widget ID, element, or selector.
### Request Example
```ts
import { executeTurnstile } from "nextjs-turnstile";
executeTurnstile('widget-123');
```
```
--------------------------------
### Imperative Control with Turnstile Ref
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Demonstrates how to control the Turnstile component imperatively using a ref. Allows resetting the CAPTCHA or getting the response token on demand. Requires the 'use client' directive.
```tsx
"use client";
import { Turnstile, TurnstileRef } from "nextjs-turnstile";
import { useRef, useState } from "react";
export default function DeferredForm() {
const turnstileRef = useRef(null);
const [token, setToken] = useState(null);
const handleReset = () => {
turnstileRef.current?.reset();
setToken(null);
};
const handleSubmit = () => {
const currentToken = turnstileRef.current?.getResponse();
if (currentToken) {
console.log("Token:", currentToken);
// Submit to server
}
};
return (
);
}
```
--------------------------------
### Render Turnstile Widget (Error Handling)
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
This example shows how to handle potential errors during the rendering of a Turnstile widget using a try-catch block. It logs success or failure messages to the console based on the outcome of the `renderTurnstile` call.
```typescript
try {
const widgetId = await renderTurnstile('#widget', {
sitekey: 'your-site-key',
});
if (!widgetId) {
console.error("Widget creation failed");
} else {
console.log("Widget created:", widgetId);
}
} catch (e) {
console.error("Render error:", e);
}
```
--------------------------------
### Turnstile Component with Imperative Control
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Demonstrates using `useRef` to get a reference to the Turnstile component for imperative control, such as executing the challenge manually. The `execution` prop must be set to 'execute'.
```tsx
import Turnstile, { TurnstileRef } from 'nextjs-turnstile';
import { useRef } from 'react';
function MyForm() {
const turnstileRef = useRef(null);
const handleSubmit = async () => {
if (turnstileRef.current) {
// Manually execute the Turnstile challenge
await turnstileRef.current.execute();
// Now you can submit the form, the token will be available
}
};
return (
);
}
```
--------------------------------
### Invisible Turnstile Widget with Deferred Execution
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
This example shows how to defer the Turnstile challenge execution until the user submits the form. It uses a ref to manually trigger the challenge with `turnstileRef.current.execute()`.
```tsx
function InvisibleDeferredForm() {
const turnstileRef = useRef(null);
const [token, setToken] = useState(null);
const handleSubmit = async () => {
if (!turnstileRef.current?.isReady()) return;
turnstileRef.current.execute();
};
useEffect(() => {
if (token) {
// Token received — submit form
fetch("/api/submit", {
method: "POST",
headers: { "cf-turnstile-response": token },
body: JSON.stringify({ /* form data */ }),
});
}
}, [token]);
return (
);
}
```
--------------------------------
### Render Turnstile Widget (Basic)
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
This is a low-level function to directly render a Turnstile widget using the Cloudflare API. It's recommended to use the React component for most cases. This example shows basic usage with a container selector and sitekey.
```typescript
import { renderTurnstile } from "nextjs-turnstile";
// Basic usage
const widgetId = await renderTurnstile('#my-container', {
sitekey: 'your-site-key',
callback: (token) => console.log('Token:', token),
});
if (!widgetId) {
console.error("Widget render failed");
}
```
--------------------------------
### Deferred Execution Pattern with Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Demonstrates a deferred execution pattern where the Turnstile challenge is initiated programmatically and the response is handled via an onSuccess callback. This pattern is useful for forms where the challenge should not start until a specific user interaction.
```tsx
"use client";
import { executeTurnstile, getTurnstileResponse } from "nextjs-turnstile";
import { useState } from "react";
export default function DeferredForm() {
const [token, setToken] = useState(null);
const handleSubmit = () => {
// Start the challenge
executeTurnstile('my-widget');
// Listen for token via onSuccess callback
};
const handlePostSolve = () => {
const token = getTurnstileResponse('my-widget');
if (token) {
setToken(token);
// Submit form with token
}
};
return (
);
}
```
--------------------------------
### Verify Turnstile Token Server-Side
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Example of server-side token verification using the verifyTurnstile function. It automatically uses the TURNSTILE_SECRET_KEY environment variable unless a custom secretKey is provided.
```ts
// Automatically used by verifyTurnstile if not overridden
const isValid = await verifyTurnstile(token);
```
```ts
// Or override
const isValid = await verifyTurnstile(token, {
secretKey: process.env.MY_CUSTOM_SECRET_KEY,
});
```
--------------------------------
### Imperative API Methods
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Provides programmatic control over the Turnstile widget using a ref. Methods include resetting the widget, removing it, getting the response token, executing the challenge, checking readiness, and retrieving the widget ID.
```APIDOC
## Imperative API (Ref)
Use a ref to control the widget programmatically.
### Ref Methods
| Method | Description |
|--------|-------------|
| `reset()` | Reset the widget for a new challenge |
| `remove()` | Remove the widget from the page |
| `getResponse()` | Get the current token (or `null`) |
| `execute()` | Start the challenge (when `execution="execute"`) |
| `isReady()` | Check if the widget is ready |
| `getWidgetId()` | Get the internal Cloudflare widget ID |
```
--------------------------------
### File Structure Overview
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
Illustrates the directory structure of the Next.js Turnstile library, showing the main entry point, components, and utility files.
```tree
src/
├── index.ts # Main entry point (re-exports)
├── components/
│ └── Turnstile.tsx # React component (260+ lines)
└── utils/
├── index.ts # Client utilities
└── verifyTurnstile.ts # Server verification
```
--------------------------------
### Server Verification with All Options
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Configure all available verification options simultaneously for comprehensive control.
```typescript
const isValid = await verifyTurnstile(token, {
secretKey: process.env.TURNSTILE_SECRET_KEY,
ip: getUserIp(request),
headers: request.headers,
action: "checkout",
hostname: "shop.example.com",
timeout: 5000,
});
```
--------------------------------
### Client Utility: Is Token Expired
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of checking if the Turnstile token for a widget has expired using its reference. Returns a boolean.
```javascript
import { isTokenExpired, TurnstileRef } from 'nextjs-turnstile';
// Assuming you have a ref to the Turnstile component:
// const turnstileRef = React.useRef(null);
// To check if the token is expired:
// const expired = isTokenExpired(turnstileRef.current);
// console.log('Is token expired?', expired);
```
--------------------------------
### Client Utility: Remove Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Example of removing a Turnstile widget from the DOM using its reference. This cleans up resources associated with the widget.
```javascript
import { removeTurnstile, TurnstileRef } from 'nextjs-turnstile';
// Assuming you have a ref to the Turnstile component:
// const turnstileRef = React.useRef(null);
// To remove the widget:
// removeTurnstile(turnstileRef.current);
```
--------------------------------
### VerifyOptions
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Options for the `verifyTurnstile()` function. These allow customization of the verification process, such as overriding the secret key, specifying the visitor's IP address, providing request headers, setting an expected action, validating the hostname, and configuring the fetch timeout.
```APIDOC
## VerifyOptions
### Description
Options for the `verifyTurnstile()` function. These allow customization of the verification process, such as overriding the secret key, specifying the visitor's IP address, providing request headers, setting an expected action, validating the hostname, and configuring the fetch timeout.
### Properties
- **secretKey** (string) - Optional - Override the secret key. Defaults to `TURNSTILE_SECRET_KEY`.
- **ip** (string) - Optional - Visitor IP address. Defaults to auto-detected.
- **headers** (`Record | Headers`) - Optional - Headers for IP detection (Pages Router).
- **action** (string) - Optional - Expected action value for validation.
- **hostname** (string) - Optional - Expected hostname for validation.
- **timeout** (number) - Optional - Fetch timeout in milliseconds. Defaults to `10000`.
### Example
```ts
await verifyTurnstile(token, {
secretKey: process.env.TURNSTILE_SECRET_KEY,
action: "contact_form",
hostname: "example.com",
timeout: 5000,
});
```
```
--------------------------------
### Get Turnstile Token After Loading
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Once `isTurnstileLoaded` returns true, you can retrieve the Turnstile token using `window.turnstile.getResponse`. Ensure the widget ID is correct.
```typescript
if (isTurnstileLoaded()) {
const token = window.turnstile.getResponse(widgetId);
console.log("Token:", token);
} else {
console.warn("Turnstile not available");
}
```
--------------------------------
### Basic Server Verification (App Router)
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Use this for automatic IP detection with default timeout and secret key settings.
```typescript
// Automatic IP detection, default timeout, default secret
const isValid = await verifyTurnstile(token);
```
--------------------------------
### Handling TurnstileError in TypeScript
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/errors.md
Example of how to catch and handle TurnstileError exceptions in your server-side code. It demonstrates checking for specific error codes like 'timeout-or-duplicate'.
```typescript
try {
await verifyTurnstile(token);
} catch (e) {
if (e instanceof TurnstileError) {
console.error("Error codes:", e.errorCodes);
console.error("Message:", e.message);
if (e.errorCodes.includes("timeout-or-duplicate")) {
// Token was already used or expired
}
} else {
// Network error or other exception
console.error("Unexpected error:", e);
}
}
```
--------------------------------
### Import Client-Side Utilities
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
Import various utility functions for managing the Turnstile script and widget on the client side.
```typescript
import {
loadTurnstileScript,
isTurnstileLoaded,
resetTurnstile,
getTurnstileResponse,
executeTurnstile,
isTokenExpired,
removeTurnstile,
renderTurnstile,
type WidgetRef,
} from "nextjs-turnstile";
```
--------------------------------
### Invisible Turnstile Mode
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Example of using Turnstile in invisible mode, where the widget is not displayed to the user. The CAPTCHA is completed in the background. Requires the 'use client' directive.
```tsx
"use client";
import { Turnstile } from "nextjs-turnstile";
import { useState } from "react";
export default function InvisibleForm() {
const [token, setToken] = useState(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!token) return;
await fetch("/api/submit", {
method: "POST",
headers: { "cf-turnstile-response": token },
body: JSON.stringify({ /* form data */ }),
});
};
return (
);
}
```
--------------------------------
### Handling Action and Hostname Mismatch Errors
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/errors.md
Verify that the provided token matches the expected action and hostname by passing them as options to `verifyTurnstile`. This snippet demonstrates handling 'action-mismatch' and 'hostname-mismatch' errors.
```typescript
import { verifyTurnstile, TurnstileError } from "nextjs-turnstile";
export async function POST(request: Request) {
const { token } = await request.json();
try {
await verifyTurnstile(token, {
action: "contact_form", // Token must have this action
hostname: "example.com", // Token must be from this domain
});
} catch (e) {
if (e instanceof TurnstileError) {
if (e.errorCodes.includes("action-mismatch")) {
// Token is from a different form/action
return Response.json(
{ error: "Token is from a different action" },
{ status: 400 }
);
}
if (e.errorCodes.includes("hostname-mismatch")) {
// Token is from a different domain (CSRF attempt?)
console.warn("Hostname mismatch - possible CSRF attempt");
return Response.json(
{ error: "Token is not valid for this domain" },
{ status: 403 }
);
}
}
throw e;
}
return Response.json({ success: true });
}
```
--------------------------------
### Get Turnstile Response Token
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Retrieves the current verification token from the Turnstile widget. Returns null if the widget has not been solved yet. Useful for server-side verification.
```typescript
const token = ref.current?.getResponse();
if (token) {
await verifyTurnstile(token);
}
```
--------------------------------
### Render Turnstile Widget (Full Options)
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Demonstrates rendering a Turnstile widget with a comprehensive set of options, including theme, size, and various callback functions for success, error, and expiration events. The container is specified as an HTMLElement.
```typescript
const widgetId = await renderTurnstile(
document.getElementById('captcha'),
{
sitekey: 'your-site-key',
theme: 'dark',
size: 'compact',
callback: (token) => handleSuccess(token),
'error-callback': (code) => handleError(code),
'expired-callback': () => handleExpire(),
}
);
```
--------------------------------
### Client Utilities for Turnstile
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Demonstrates the usage of client utility functions like resetTurnstile and getTurnstileResponse with a WidgetRef.
```typescript
import {
resetTurnstile,
getTurnstileResponse,
WidgetRef,
} from "nextjs-turnstile";
const widgetRef: WidgetRef = "widget-0";
resetTurnstile(widgetRef);
const token = getTurnstileResponse(widgetRef);
```
--------------------------------
### Get Turnstile Response Utility
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Retrieves the current Turnstile token from the widget associated with the provided widget reference. Returns the token string or null if no token is available.
```typescript
declare function getTurnstileResponse(widgetRef: WidgetRef): string | null;
```
--------------------------------
### Get Client IP Address Function
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/ANALYSIS_SUMMARY.txt
Asynchronously retrieves the client's IP address from request headers. Useful for server-side logic that requires IP information.
```typescript
declare function getClientIp(initHeaders?: HeadersInit): Promise;
```
--------------------------------
### TurnstileAppearance Type Definition
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Controls the visibility of the Turnstile widget. 'always' keeps it visible, 'execute' shows it when a challenge starts, and 'interaction-only' displays it only when user interaction is needed.
```typescript
type TurnstileAppearance = "always" | "execute" | "interaction-only"
```
--------------------------------
### Server Verification with Action Validation
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Ensure the token originates from the expected form or action.
```typescript
// Ensure token is from the expected form/action
const isValid = await verifyTurnstile(token, {
action: "contact_form",
});
```
--------------------------------
### Get Client IP Address
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/verifyTurnstile.md
Utility function to extract the client IP address from request context. Tries next/headers, falls back to provided headers, or returns undefined.
```typescript
async function getClientIp(
initHeaders?: Record | Headers
): Promise
```
```typescript
import { getClientIp } from "nextjs-turnstile";
// In App Router (automatic)
const ip = await getClientIp();
// In Pages Router (with headers)
const ip = await getClientIp(req.headers);
```
--------------------------------
### Configure Environment Variables
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Set up your Cloudflare Turnstile site key and secret key as environment variables in your .env.local file. These keys are essential for both client-side rendering and server-side verification.
```env
# .env.local
NEXT_PUBLIC_TURNSTILE_SITE_KEY=your_site_key_here
TURNSTILE_SECRET_KEY=your_secret_key_here
```
--------------------------------
### Poll Token Expiration
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
This example demonstrates how to periodically check if a Turnstile token has expired using `isTokenExpired` and reset it if necessary. It sets up an interval to check the token status every second.
```typescript
const checkTokenStatus = (widgetId: string) => {
const interval = setInterval(() => {
if (isTokenExpired(widgetId)) {
console.log("Token expired, resetting...");
resetTurnstile(widgetId);
clearInterval(interval);
}
}, 1000); // Check every second
};
```
--------------------------------
### Import Server-Side Verification Functions
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
Import functions for server-side verification of Turnstile tokens.
```typescript
import { verifyTurnstile, TurnstileError } from "nextjs-turnstile";
```
--------------------------------
### VerifyOptions Interface
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Defines the available options for server-side Turnstile verification.
```typescript
interface VerifyOptions {
secretKey?: string;
ip?: string;
headers?: Record | Headers;
action?: string;
hostname?: string;
timeout?: number;
}
```
--------------------------------
### Get Turnstile Widget ID
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Turnstile-Component.md
Retrieves the internal widget ID assigned by Cloudflare to the Turnstile instance. This is useful for advanced debugging or integration scenarios. Returns undefined if the widget has not yet been rendered.
```typescript
const widgetId = ref.current?.getWidgetId();
console.log("Widget ID:", widgetId);
```
--------------------------------
### Imperative Turnstile Control with TurnstileRef
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/types.md
Provides an imperative handle for controlling the Turnstile widget using `useRef`. Allows for actions like resetting, removing, getting responses, executing challenges, and checking readiness.
```typescript
interface TurnstileRef {
reset: () => void;
remove: () => void;
getResponse: () => string | null;
execute: () => void;
isReady: () => boolean;
getWidgetId: () => string | undefined;
}
```
```tsx
const ref = useRef(null);
// In handlers
ref.current?.reset();
const token = ref.current?.getResponse();
const ready = ref.current?.isReady();
ref.current?.execute();
```
--------------------------------
### Server-Side Turnstile Verification with Advanced Options
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Configure server-side Turnstile verification with advanced options to override the secret key, specify the user's IP address, provide request headers, set an action, match the hostname, or adjust the fetch timeout.
```ts
const ok = await verifyTurnstile(token, {
secretKey: "custom-secret-key", // Override secret key
ip: "1.2.3.4", // User's IP (auto-detected if omitted)
headers: request.headers, // For IP detection in Pages Router
action: "login", // Reject if action doesn't match
hostname: "example.com", // Reject if hostname doesn't match
timeout: 5000, // Fetch timeout in ms (default: 10 000)
});
```
--------------------------------
### Client Utilities
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/00-START-HERE.md
Utility functions for interacting with the Turnstile script and widget on the client-side.
```APIDOC
## Client Utilities
### Description
These utility functions provide direct access to the Turnstile client-side API for managing the script loading, widget state, and token retrieval.
### Functions
- **loadTurnstileScript()**: Loads the Turnstile JavaScript script into the DOM if it's not already loaded.
- **isTurnstileLoaded()**: Returns a boolean indicating whether the Turnstile script is currently loaded and ready.
- **resetTurnstile(widgetRef)**: Resets the Turnstile widget associated with the provided `widgetRef`. This is useful for re-challenging the user.
- **getTurnstileResponse(widgetRef)**: Retrieves the current Turnstile token from the widget associated with `widgetRef`. Returns `null` if no token is available.
- **executeTurnstile(widgetRef)**: Programmatically triggers the Turnstile challenge for the widget associated with `widgetRef`.
- **isTokenExpired(widgetRef)**: Checks if the Turnstile token for the widget associated with `widgetRef` has expired. Returns `true` if expired, `false` otherwise.
```
--------------------------------
### isTurnstileLoaded
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Checks if the Turnstile script has been loaded and is ready to use. This is useful to ensure that the `window.turnstile` object is available before attempting to render or interact with widgets.
```APIDOC
## isTurnstileLoaded
### Description
Checks if the Turnstile script has been loaded and is ready to use.
### Signature
```ts
function isTurnstileLoaded(): boolean
```
### Returns
`true` if `window.turnstile` is available, `false` otherwise.
### Example
```ts
import { isTurnstileLoaded } from "nextjs-turnstile";
if (isTurnstileLoaded()) {
window.turnstile.render('#widget', { sitekey: 'xxx' });
} else {
console.log("Script not loaded yet");
}
```
```
--------------------------------
### Get Turnstile Verification Token
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/api-reference/Client-Utilities.md
Use `getTurnstileResponse` to retrieve the current verification token from a Turnstile widget. This function returns the token as a string if the widget is solved, or `null` if it's not yet solved or doesn't exist. It's commonly used within form submission handlers.
```typescript
import { getTurnstileResponse } from "nextjs-turnstile";
// Get token by widget ID
const token = getTurnstileResponse('widget-123');
if (token) {
console.log("Token ready for verification:", token);
// Send to server for verification
} else {
console.log("Widget not solved yet or doesn't exist");
}
```
```typescript
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const token = getTurnstileResponse('#my-turnstile');
if (!token) {
alert("Please complete the CAPTCHA");
return;
}
const response = await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ token, data: /* form data */ }),
});
if (response.ok) {
resetTurnstile('#my-turnstile');
}
};
```
--------------------------------
### Client-Side Utilities
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/INDEX.md
Low-level functions for controlling the Turnstile widget on the client-side, including script loading, widget rendering, and token retrieval. Useful for advanced scenarios and imperative control.
```APIDOC
## Client-Side Utilities
### Description
Provides a set of low-level JavaScript functions for interacting with the Cloudflare Turnstile widget directly. These utilities are useful for advanced use cases, such as managing multiple widgets, controlling widget behavior imperatively, or integrating with custom UI elements. They are implemented to be safe for Server-Side Rendering (SSR) environments.
### Functions
#### `loadTurnstileScript(options?: LoadScriptOptions): Promise`
Loads the Cloudflare Turnstile JavaScript SDK. It ensures the script is loaded only once.
**Parameters:**
- `options` (object) - Optional. Configuration for loading the script.
- `siteKey` (string) - Required if not already configured via environment variables or previous loads. Your Cloudflare Turnstile site key.
- ` 100% ` (string) - Optional. The language for the Turnstile widget.
- `appearance` (string) - Optional. The appearance mode of the widget ('always', 'execute', 'none').
- `execution` (string) - Optional. The execution mode ('auto', 'execute').
- `retryInterval` (number) - Optional. The interval in milliseconds to retry loading the script if it fails.
- `retryDelay` (number) - Optional. The delay in milliseconds before retrying.
**Returns:**
- `Promise` - A promise that resolves when the script is successfully loaded.
#### `renderTurnstile(elementId: string, options?: RenderOptions): Promise`
Renders a Turnstile widget into a specified DOM element.
**Parameters:**
- `elementId` (string) - Required. The ID of the HTML element where the widget should be rendered.
- `options` (object) - Optional. Configuration options for the widget rendering.
- `siteKey` (string) - Required if not globally configured. Your Cloudflare Turnstile site key.
- `theme` (string) - Optional. The theme of the widget ('light' or 'dark').
- `action` (string) - Optional. A custom action name for the widget.
- `cData` (string) - Optional. Client-side data to be passed to the widget.
- `callback` (function) - Optional. Callback for successful validation.
- `'error-callback'` (function) - Optional. Callback for widget errors.
- `'expired-callback'` (function) - Optional. Callback for widget expiration.
- `'unsupported-callback'` (function) - Optional. Callback for unsupported widget.
- `'before-interactive-callback'` (function) - Optional. Callback before widget interaction.
- `'after-interactive-callback'` (function) - Optional. Callback after widget interaction.
- `'too-many-requests-callback'` (function) - Optional. Callback for too many requests.
- `'client-response-callback'` (function) - Optional. Callback with client response.
- `language` (string) - Optional. The language of the widget.
- `appearance` (string) - Optional. The appearance of the widget ('always', 'execute', 'none').
- `execution` (string) - Optional. The execution mode of the widget ('auto', 'execute').
- `retryInterval` (number) - Optional. The retry interval in milliseconds.
- `retryDelay` (number) - Optional. The delay in milliseconds before retrying.
- `size` (string) - Optional. The size of the widget ('normal', 'compact').
**Returns:**
- `Promise` - A promise that resolves with the widget ID.
#### `getTurnstileToken(elementId: string): Promise`
Retrieves the Turnstile token for a widget rendered in a specific element.
**Parameters:**
- `elementId` (string) - Required. The ID of the HTML element containing the widget.
**Returns:**
- `Promise` - A promise that resolves with the token string, or `null` if the token cannot be retrieved.
#### `resetTurnstile(elementId: string): Promise`
Resets a specific Turnstile widget.
**Parameters:**
- `elementId` (string) - Required. The ID of the HTML element containing the widget to reset.
**Returns:**
- `Promise` - A promise that resolves when the widget is reset.
#### `executeTurnstile(elementId: string): Promise`
Executes a specific Turnstile widget, typically to trigger validation.
**Parameters:**
- `elementId` (string) - Required. The ID of the HTML element containing the widget to execute.
**Returns:**
- `Promise` - A promise that resolves when the widget execution is triggered.
### Example Usage
```javascript
import { loadTurnstileScript, renderTurnstile, getTurnstileToken, resetTurnstile } from 'nextjs-turnstile/client';
async function initializeWidget() {
await loadTurnstileScript({ siteKey: 'YOUR_SITE_KEY' });
const widgetId = await renderTurnstile('turnstile-container', {
action: 'custom_action',
callback: (token) => {
console.log('Token received:', token);
// Send token to server for verification
}
});
console.log('Widget rendered with ID:', widgetId);
}
async function getToken() {
const token = await getTurnstileToken('turnstile-container');
console.log('Current token:', token);
}
async function resetWidget() {
await resetTurnstile('turnstile-container');
console.log('Widget reset.');
}
// Call initializeWidget() when your component mounts or as needed.
```
```
--------------------------------
### Deferred Turnstile Execution
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/configuration.md
Sets up the Turnstile component for deferred execution, where the widget is hidden and the challenge only runs after an explicit call to `execute()`. This reduces initial load time and is ideal for scenarios where the widget should not be immediately visible.
```tsx
// In submit handler
turnstileRef.current?.execute();
```
--------------------------------
### Basic Verification with Boolean Check
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/errors.md
Use this snippet for simple fail-fast scenarios where only a true/false outcome is needed. It performs verification and returns an error response if the token is invalid.
```typescript
import { verifyTurnstile } from "nextjs-turnstile";
export async function POST(request: Request) {
const { token } = await request.json();
const isValid = await verifyTurnstile(token);
if (!isValid) {
return Response.json(
{ error: "CAPTCHA verification failed" },
{ status: 400 }
);
}
// Process the form...
return Response.json({ success: true });
}
```
--------------------------------
### Invisible Turnstile Widget with Auto-run
Source: https://github.com/davodm/nextjs-turnstile/blob/main/README.md
Use this pattern for invisible Turnstile widgets that automatically run the challenge when the component mounts. The token is passed to onSuccess as soon as it's available.
```tsx
function InvisibleAutoForm() {
const [token, setToken] = useState(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!token) return;
await fetch("/api/submit", {
method: "POST",
headers: { "cf-turnstile-response": token },
body: JSON.stringify({ /* form data */ }),
});
};
return (
);
}
```
--------------------------------
### Client-Side Turnstile Utility Functions
Source: https://github.com/davodm/nextjs-turnstile/blob/main/_autodocs/00-START-HERE.md
Manage the Turnstile widget and its state using client-side utility functions. These include loading the script, checking its readiness, resetting the widget, retrieving the response token, executing the challenge, and checking token expiry.
```ts
loadTurnstileScript() // Load script
isTurnstileLoaded() // Check if ready
resetTurnstile(widgetRef) // Reset widget
getTurnstileResponse(widgetRef) // Get token
executeTurnstile(widgetRef) // Execute challenge
isTokenExpired(widgetRef) // Check expiry
```