Captcha

Protect your forms and API call with captcha validation.

Captcha Preview

Providers

VitNode supports multiple captcha providers. You can choose the one that fits your needs. Currently, we support:

If you need more providers, feel free to open a Feature Request on our GitHub repository :)

Usage

In this example, we will show you how to use captcha in your forms. We will use the AutoForm component to render the form and handle the captcha validation.

Activate captcha in route

Add withCaptcha to your route config to enable captcha validation for this route.

plugins/{plugin_name}/src/routes/example.ts
import { buildRoute } from "@vitnode/core/api/lib/route";

export const exampleRoute = buildRoute({
  pluginId: CONFIG_PLUGIN.pluginId,
  route: {
    method: "post",
    description: "Create a new user",
    path: "/sign_up",
    withCaptcha: true, 
  },
  handler: async c => {},
});

Get config from middleware API

Get captcha config from middleware API in your view and pass it to your 'use client'; component.

plugins/{plugin_name}/src/app/sing_up/page.tsx
import { getMiddlewareApi } from "@vitnode/core/lib/api/get-middleware-api"; 

export const SignUpView = async () => {
  const { captcha } = await getMiddlewareApi(); 

  return <FormSignUp captcha={captcha} />;
};

Use in form

Get the captcha config from the props and pass it to the AutoForm component. This will render the captcha widget in your form.

plugins/{plugin_name}/src/components/form/sign-up/sign-up.tsx
"use client";

import { AutoForm } from "@vitnode/core/components/form/auto-form";

export const FormSignUp = ({
  captcha, 
}: {
  captcha: z.infer<typeof routeMiddlewareSchema>["captcha"]; 
}) => {
  return (
    <AutoForm<typeof formSchema>
      captcha={captcha} 
      fields={[]}
      formSchema={formSchema}
    />
  );
};

AutoForm

Lear more about the AutoForm component and how to use it.

Submit form with captcha

In your form submission handler, you can get the captchaToken from the form submission context and pass it to your mutation API.

plugins/{plugin_name}/src/components/form/sign-up/sign-up.tsx
"use client";

import {
  AutoForm,
  type AutoFormOnSubmit, 
} from "@vitnode/core/components/form/auto-form";

export const FormSignUp = ({
  captcha,
}: {
  captcha: z.infer<typeof routeMiddlewareSchema>["captcha"];
}) => {
  const onSubmit: AutoFormOnSubmit<typeof formSchema> = async (
    values,
    form,
    { captchaToken }, 
  ) => {
    // Call your mutation API with captcha token
    await mutationApi({
      ...values,
      captchaToken, 
    });

    // Handle success or error
  };

  return (
    <AutoForm<typeof formSchema>
      captcha={captcha}
      fields={[]}
      onSubmit={onSubmit} 
      formSchema={formSchema}
    />
  );
};

Next, you need to set captchaToken in your mutation API call. This token is provided by the AutoForm component when the form is submitted.

plugins/{plugin_name}/src/components/form/sign-up/mutation-api.ts
"use server";

import type { z } from "zod";

import { fetcher } from "@vitnode/core/lib/fetcher";

export const mutationApi = async ({
  captchaToken, 
  ...input
}:
z.infer<typeof zodSignUpSchema> & { captchaToken: string }) => {
  const res = await fetcher(usersModule, {
    path: "/sign_up",
    method: "post",
    module: "users",
    captchaToken, 
    args: {
      body: input,
    },
  });

  if (res.status !== 201) {
    return { error: await res.text() };
  }

  const data = await res.json();

  return { data };
};
Captcha - VitNode