Next.js
Add Centinel Analytica to your Next.js application.
Overview
Centinel validates each request before it reaches your application. Suspicious requests are blocked or redirected to a verification page. The client script helps distinguish legitimate users from bots.
Blocked requests are redirected to /block by default. Create this page in your app or customize the redirect URL in your middleware configuration.
Prerequisites
- Site key (public, used by the browser script)
- Secret key (server-only, used for validation)
Install
In your Next.js project:
npm install @centinel/nextjsConfigure
Add your Centinel keys to .env:
CENTINEL_SITE_KEY=YOUR_SITE_KEY
CENTINEL_SECRET_KEY=YOUR_SECRET_KEY
NEXT_PUBLIC_CENTINEL_SITE_KEY=YOUR_SITE_KEYKey safety
Use CENTINEL_SECRET_KEY server-side only. Don't expose it to the browser.
Which site key to use
Use CENTINEL_SITE_KEY for server-side code (layouts, middleware). Use
NEXT_PUBLIC_CENTINEL_SITE_KEY if using CentinelLayout in client-side pages.
Add CentinelLayout to your root layout:
// app/layout.tsx (server-side)
import { CentinelLayout } from '@centinel/nextjs';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
<CentinelLayout siteKey={process.env.CENTINEL_SITE_KEY!}>
{children}
</CentinelLayout>
</body>
</html>
);
}Or if using in a client-side page:
// app/page.tsx (client-side)
'use client';
import { CentinelLayout } from '@centinel/nextjs';
export default function HomePage(): JSX.Element {
return (
<CentinelLayout siteKey={process.env.NEXT_PUBLIC_CENTINEL_SITE_KEY!}>
{/* Your page content */}
</CentinelLayout>
);
}Choose between automatic middleware or manual validation:
Create middleware.ts in your project root:
import { createCentinelMiddlewareFromEnv } from '@centinel/nextjs';
export default createCentinelMiddlewareFromEnv();
export const config = {
matcher: ['/api/:path*', '/dashboard/:path*']
};Use in specific API routes when middleware doesn't fit:
// app/api/login/route.ts
import { createRequestValidatorFromEnv } from '@centinel/nextjs';
import { NextRequest, NextResponse } from 'next/server';
const { isBot } = createRequestValidatorFromEnv();
export async function POST(request: NextRequest) {
if (await isBot(request)) {
return NextResponse.json({ error: 'Blocked' }, { status: 403 });
}
return handleLogin(request);
}Or with custom configuration:
// app/api/protected/route.ts
import { createRequestValidator } from '@centinel/nextjs';
import { NextRequest, NextResponse } from 'next/server';
const { isBot } = createRequestValidator({
siteKey: 'YOUR_SITE_KEY',
secretKey: 'YOUR_SECRET_KEY'
});
export async function POST(request: NextRequest) {
if (await isBot(request)) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
}
// Your protected logic
}Custom configuration
Pass config directly instead of using environment variables:
import { createCentinelMiddleware } from '@centinel/nextjs';
export default createCentinelMiddleware({
siteKey: 'YOUR_SITE_KEY',
secretKey: 'YOUR_SECRET_KEY'
});Route matching
Specify which routes to protect:
export const config = {
matcher: [
'/api/:path*', // All API routes
'/dashboard/:path*', // Dashboard pages
'/admin/:path*' // Admin area
]
};Changelog
- v1.2.2 — Response header passthrough