Skip to content
FitMyKBVerify

FitMyKB Verify

Add a CAPTCHA to a Next.js form

Load the widget with next/script, read the token in a server action, and check it with siteverify before you send anything.

Keys

Add your site key as NEXT_PUBLIC_FMK_SITE_KEY and your secret as FMK_SECRET in .env.local. Only the site key reaches the browser.

The form

next/script loads api.js once. The widget finds the .fmk-captcha box, and when the visitor passes it adds fmk-captcha-response to the form, so the server action receives it with the other fields.

TSX · the form
// app/contact/page.tsx
import Script from "next/script";
import { send } from "./actions";

export default function Contact() {
  return (
    <form action={send}>
      <input name="email" type="email" required />
      <textarea name="message" required />
      <div className="fmk-captcha" data-sitekey={process.env.NEXT_PUBLIC_FMK_SITE_KEY} />
      <button>Send</button>
      <Script src="https://fitmykb.com/captcha/api.js" strategy="afterInteractive" />
    </form>
  );
}

The server action

Check the token before doing anything else. The reply also carries a score from 0 to 1 and, with score-only mode, the action name, if you want to treat borderline visitors differently.

TypeScript · server action
// app/contact/actions.ts
"use server";

export async function send(form: FormData) {
  const reply = await fetch("https://fitmykb.com/captcha/siteverify", {
    method: "POST",
    body: new URLSearchParams({
      secret: process.env.FMK_SECRET!,
      response: String(form.get("fmk-captcha-response") ?? ""),
    }),
    cache: "no-store",
  }).then((r) => r.json());
  if (!reply.success) throw new Error("Please complete the check.");
  // …send the message
}

Pages Router and API routes

The same check works in pages/api: read req.body['fmk-captcha-response'] and post it to siteverify the same way.

Deploying on Vercel

Add both environment variables in the project settings. Preview deployments use *.vercel.app addresses, so add them to the website's domains or keep a separate test-mode website for previews.

Get free keys · Full developer docs

Questions

Good questions

Anything else? Read the docs or ask us.

Does it work with React Server Components?

Yes: the form is a server component and only next/script runs in the browser.