🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

next-turnstile

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

next-turnstile

Cloudflare Turnstile integration for Next.js applications

1.0.4
latest
npm
Version published
Weekly downloads
2.7K
-33.88%
Maintainers
1
Weekly downloads
 
Created
Source

Next-Turnstile

A type-safe, feature-rich integration of Cloudflare Turnstile for Next.js applications. This package provides both client and server-side components for seamless CAPTCHA integration.

npm version License: MIT

Features

  • 🔒 Type-safe: Full TypeScript support
  • 🎨 Customizable: Extensive styling and behavior options
  • 🧪 Sandbox Mode: Built-in support for development testing
  • Server Validation: Easy token verification
  • 📱 Responsive: Works across all device sizes
  • 🔄 Auto-reload: Configurable token refresh
  • 🌙 Theme Support: Light, dark, and auto themes
  • 🌐 i18n Ready: Multiple language support

Installation

# npm
npm install next-turnstile

# yarn
yarn add next-turnstile

# pnpm
pnpm add next-turnstile

# bun
bun add next-turnstile

Quick Start

Client-Side Usage

import { Turnstile } from "next-turnstile";

function MyForm() {
  const handleVerify = (token: string) => {
    // Handle the verification token
    console.log("Verification successful:", token);
  };

  return (
    <Turnstile siteKey="your-site-key" onVerify={handleVerify} theme="light" />
  );
}

Server-Side Validation

import { validateTurnstileToken } from "next-turnstile";

async function validateToken(token: string) {
  try {
    const result = await validateTurnstileToken({
      token,
      secretKey: process.env.TURNSTILE_SECRET_KEY,
    });

    if (result.success) {
      // Token is valid
      return true;
    }
  } catch (error) {
    console.error("Validation failed:", error);
  }
  return false;
}

API Reference

Turnstile Component Props

PropTypeDefaultDescription
siteKeystringRequiredYour Cloudflare Turnstile site key
onVerify(token: string) => void-Callback when verification succeeds
onError(error: unknown) => void-Callback when an error occurs
onExpire() => void-Callback when the token expires
onLoad() => void-Callback when the widget loads
theme'light' | 'dark' | 'auto''auto'Widget theme
size'normal' | 'compact''normal'Widget size
appearance'always' | 'execute' | 'interaction-only''always'When to show the widget
retry'auto' | 'never''auto'Retry behavior on failure
retryIntervalnumber8000Milliseconds between retries
refreshExpired'auto' | 'manual' | 'never''auto'Token refresh behavior
languagestring-Widget language code
idstring'turnstile-widget'Container element ID
classNamestring-Additional CSS classes
sandboxboolean | pass | block | pass-invisible | block-invisiblefalseEnable sandbox mode

Server Validation Options

OptionTypeRequiredDescription
tokenstringYesThe token from the client
secretKeystringYesYour Turnstile secret key
remoteipstringNoUser's IP address
idempotencyKeystringNoUnique request identifier
sandboxboolean| pass | fail | errorNoEnable sandbox mode

Advanced Usage

With Form Submission

import { Turnstile } from "next-turnstile";

export default function Form() {
  const [token, setToken] = useState<string>();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!token) return;

    const response = await fetch("/api/submit", {
      method: "POST",
      body: JSON.stringify({ token }),
      headers: { "Content-Type": "application/json" },
    });

    // Handle response...
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" required />
      <Turnstile
        siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY!}
        onVerify={setToken}
      />
      <button type="submit" disabled={!token}>
        Submit
      </button>
    </form>
  );
}

Server Action Validation

import { validateTurnstileToken } from "next-turnstile";

async function submitForm(formData: FormData) {
  "use server";

  const token = formData.get("cf-turnstile-response");
  if (!token || typeof token !== "string") {
    return { error: "No token provided" };
  }

  const result = await validateTurnstileToken({
    token,
    secretKey: process.env.TURNSTILE_SECRET_KEY!,
  });

  if (!result.success) {
    return { error: "Invalid token" };
  }

  // Process form submission...
}

Development Mode

During development, you can use sandbox mode to test without real credentials:

<Turnstile
  siteKey="1x00000000000000000000AA"
  sandbox={process.env.NODE_ENV === "development"}
  onVerify={handleVerify}
/>

Dark Mode Support

<Turnstile
  siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY!}
  theme="dark"
  onVerify={handleVerify}
/>

With Custom Styling

<Turnstile
  siteKey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY!}
  className="my-turnstile-widget"
  onVerify={handleVerify}
/>

<style>
  .my-turnstile-widget {
    margin: 1rem 0;
    /* Note: Internal widget styling is limited by Turnstile */
  }
</style>

Development and Contributing

  • Clone the repository
  • Install dependencies:
    pnpm install
    
  • Start development:
    pnpm dev
    

License

MIT © Jed Patterson

Credits

Built with ❤️ using:

Keywords

nextjs

FAQs

Package last updated on 05 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts