Protect your applications from sophisticated bots with invisible CAPTCHA. Modern bots execute JavaScript, solve CAPTCHAs, and navigate like real users - BotID detects and blocks them without disrupting legitimate traffic.
Before setting up BotID, ensure you have a JavaScript project deployed on Vercel.
npm install botid
For complete documentation, visit the official Vercel BotID docs.
Use the appropriate configuration method for your framework to set up proxy rewrites:
Next.js
// next.config.js
import { withBotId } from 'botid/next/config';
const nextConfig = {
// Your existing Next.js config
};
export default withBotId(nextConfig);
Nuxt
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['botid/nuxt'],
});
Other Frameworks
For other frameworks, add the following to your vercel.json:
{
"rewrites": [
{
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/a-4-a/c.js",
"destination": "https://api.vercel.com/bot-protection/v1/challenge"
},
{
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/:path*",
"destination": "https://api.vercel.com/bot-protection/v1/proxy/:path*"
}
],
"headers": [
{
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/:path*",
"headers": [
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
}
]
}
]
}
Next.js 15.3+ (Recommended)
Use initBotId() in instrumentation-client.ts:
// instrumentation-client.ts
import { initBotId } from 'botid/client/core';
initBotId({
protect: [
{
path: '/api/checkout',
method: 'POST',
},
{
path: '/team/*/activate',
method: 'POST',
},
{
path: '/api/user/*',
method: 'POST',
},
],
});
Next.js < 15.3
Mount the <BotIdClient/> component in your layout:
// app/layout.tsx
import { BotIdClient } from 'botid/client';
import { ReactNode } from 'react';
const protectedRoutes = [
{
path: '/api/checkout',
method: 'POST',
},
];
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en">
<head>
<BotIdClient protect={protectedRoutes} />
</head>
<body>{children}</body>
</html>
);
}
Nuxt
// plugins/botid.client.ts
import { initBotId } from 'botid/client/core';
export default defineNuxtPlugin({
enforce: 'pre',
setup() {
initBotId({
protect: [{ path: '/api/post-data', method: 'POST' }],
});
},
});
SvelteKit
// src/hooks.client.ts
import { initBotId } from 'botid/client/core';
export function init() {
initBotId({
protect: [
{
path: '/api/post-data',
method: 'POST',
},
],
});
}
Use checkBotId() on your protected routes:
API Routes
import { checkBotId } from 'botid/server';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const verification = await checkBotId();
if (verification.isBot) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
}
// Your protected logic here
}
Server Actions
'use server';
import { checkBotId } from 'botid/server';
export async function createUser(formData: FormData) {
const verification = await checkBotId();
if (verification.isBot) {
throw new Error('Access denied');
}
// Process user data
}
For advanced bot protection, enable BotID Deep Analysis in your Vercel Dashboard:
MIT - See LICENSE for more information.