@centinel/nextjs
Version:
Package designed to add Centinel Analytica functionality to Next.js applications
144 lines (107 loc) • 3.17 kB
Markdown
# Centinel Analytica Next.js Integration
Bot protection middleware for Next.js applications.
## Installation
```bash
npm install @centinel/nextjs
```
## Setup
### 1. Environment Variables
```env
CENTINEL_SITE_KEY=your_site_key_here
CENTINEL_SECRET_KEY=your_secret_key_here
NEXT_PUBLIC_CENTINEL_SITE_KEY=your_site_key_here
```
### 2. Client Script
```typescript
// app/layout.tsx
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>
);
}
```
### 3. Middleware
#### Simple Middleware
```typescript
import { createCentinelMiddlewareFromEnv } from '@centinel/nextjs';
import { NextRequest } from 'next/server';
const centinelMiddleware = createCentinelMiddlewareFromEnv();
export default async function middleware(request: NextRequest) {
const result = await centinelMiddleware(request);
return result.response;
}
export const config = {
matcher: ['/api/:path*', '/dashboard/:path*']
};
```
#### With Multiple Middlewares
```typescript
import { createCentinelMiddleware } from '@centinel/nextjs';
import { NextRequest, NextResponse } from 'next/server';
const centinelMiddleware = createCentinelMiddleware({
siteKey: process.env.CENTINEL_SITE_KEY!,
secretKey: process.env.CENTINEL_SECRET_KEY!
});
export default async function middleware(request: NextRequest) {
const result = await centinelMiddleware(request);
if (result.should_intercept) {
return result.response;
}
// Your other middleware logic
return NextResponse.next();
}
export const config = {
matcher: ['/api/:path*', '/dashboard/:path*']
};
```
#### Manual Validation (API Routes)
```typescript
// 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);
}
```
## Advanced
### CentinelResult
```typescript
interface CentinelResult {
response: NextResponse;
decision: 'allow' | 'block' | 'redirect' | 'not_matched';
should_intercept: boolean;
}
```
- `should_intercept: true` → `block` or `redirect` (return immediately)
- `should_intercept: false` → `allow` or `not_matched` (continue)
### CentinelMiddleware Class
```typescript
import { CentinelMiddleware } from '@centinel/nextjs';
const centinel = new CentinelMiddleware({
siteKey: process.env.CENTINEL_SITE_KEY!,
secretKey: process.env.CENTINEL_SECRET_KEY!,
timeout: 1000, // ms (default: 500)
debugMode: true
});
const result = await centinel.validate({ request });
```
### Check Cookie in API Routes
```typescript
export async function POST(request: NextRequest) {
if (!request.cookies.get('_centinel')) {
return NextResponse.json({ error: 'Blocked' }, { status: 403 });
}
// ...
}
```