AgentShield
Server Integrations

Next.js Integration

Edge-optimized AI agent detection for Next.js applications

Overview

The AgentShield Next.js integration provides seamless AI agent detection and protection for your Next.js applications. With edge runtime optimization and full App Router support, it delivers enterprise-grade protection with minimal performance impact.

Features

Performance

  • Edge Runtime Compatible - Runs at the edge for ultra-low latency
  • < 2ms overhead - Minimal impact on response times
  • Streaming Support - Works with Next.js streaming responses
  • ISR Compatible - Works with Incremental Static Regeneration

Protection

  • Middleware-based - Protect all routes automatically
  • Route Matching - Fine-grained control over protected paths
  • Session Tracking - Track agents across multiple requests
  • Custom Actions - Flexible response strategies

React Integration

  • Server Components - Full RSC support
  • Client Hooks - React hooks for client-side detection
  • TypeScript - Full type safety
  • App Router - Native App Router support

Installation

npm install @kya-os/agentshield-nextjs

Quick Setup

1. Create Middleware

Create middleware.ts in your project root:

import { agentShield } from '@kya-os/agentshield-nextjs';

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  onAgentDetected: 'block',
  confidenceThreshold: 0.8,
});

export const config = {
  matcher: [
    /*
     * Match all request paths except:
     * - api routes
     * - static files
     * - image optimization files
     * - favicon
     */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};

2. Server Component Usage

// app/page.tsx
import { headers } from 'next/headers';

export default function Page() {
  const headersList = headers();
  const detection = headersList.get('x-agentshield-detection');
  
  if (detection) {
    const result = JSON.parse(detection);
    if (result.isAgent) {
      return <div>Access Restricted</div>;
    }
  }
  
  return <div>Welcome!</div>;
}

3. Client Component Usage

'use client';

import { useAgentDetection } from '@kya-os/agentshield-nextjs';

export function ProtectedContent() {
  const { isAgent, confidence, isLoading } = useAgentDetection();
  
  if (isLoading) return <div>Checking...</div>;
  if (isAgent) return <div>Content not available</div>;
  
  return <div>Premium content here</div>;
}

1. Create Middleware

Create middleware.ts in your project root:

import { agentShield } from '@kya-os/agentshield-nextjs';

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  onAgentDetected: 'block',
  confidenceThreshold: 0.8,
});

export const config = {
  matcher: '/:path*',
};

2. API Route Protection

// pages/api/protected.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const detection = req.headers['x-agentshield-detection'];
  
  if (detection) {
    const result = JSON.parse(detection as string);
    if (result.isAgent) {
      return res.status(403).json({ error: 'Access denied' });
    }
  }
  
  res.status(200).json({ data: 'Protected data' });
}

3. Page Component Usage

// pages/protected.tsx
import { useAgentDetection } from '@kya-os/agentshield-nextjs';

export default function ProtectedPage() {
  const { isAgent, confidence } = useAgentDetection();
  
  if (isAgent) {
    return <div>This content is protected</div>;
  }
  
  return <div>Welcome to the protected page</div>;
}

Configuration Options

Basic Configuration

agentShield({
  // Required
  apiKey: string;                    // Your API key
  
  // Detection Settings
  onAgentDetected: 'block' | 'log' | 'redirect' | 'custom';
  confidenceThreshold: number;       // 0-1 (default: 0.8)
  
  // Response Customization
  blockMessage?: string;             // Custom block message
  redirectUrl?: string;              // Redirect URL for agents
  customHandler?: (req, result) => Response; // Custom response handler
  
  // Advanced Options
  sessionTracking?: {
    enabled: boolean;               // Track sessions (default: true)
    storage?: 'cookie' | 'header';  // Storage method
    duration?: number;              // Session duration in ms
  };
  
  skipPaths?: string[];             // Paths to skip detection
  allowedAgents?: string[];         // Whitelisted user agents
  
  // Performance
  cacheDetection?: boolean;         // Cache detection results
  cacheDuration?: number;           // Cache TTL in seconds
  
  // Debug
  debug?: boolean;                  // Enable debug logging
  logLevel?: 'error' | 'warn' | 'info' | 'debug';
});

Environment Variables

# .env.local
AGENTSHIELD_API_KEY=your_api_key_here
AGENTSHIELD_ACTION=block
AGENTSHIELD_THRESHOLD=0.8
AGENTSHIELD_DEBUG=false

Advanced Configuration Example

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  onAgentDetected: 'custom',
  confidenceThreshold: 0.85,
  
  // Custom response handler
  customHandler: async (req, result) => {
    // Log detection
    await logToAnalytics({
      agent: result.signals.userAgent,
      confidence: result.confidence,
      path: req.nextUrl.pathname,
    });
    
    // Custom response based on confidence
    if (result.confidence > 0.95) {
      return new Response('Access Denied', { status: 403 });
    } else if (result.confidence > 0.8) {
      return NextResponse.redirect(new URL('/challenge', req.url));
    }
    
    return NextResponse.next();
  },
  
  // Session tracking
  sessionTracking: {
    enabled: true,
    storage: 'cookie',
    duration: 24 * 60 * 60 * 1000, // 24 hours
  },
  
  // Skip certain paths
  skipPaths: [
    '/api/webhooks',
    '/health',
    '/robots.txt',
  ],
  
  // Allow specific bots
  allowedAgents: [
    'Googlebot',
    'Bingbot',
  ],
  
  // Performance optimization
  cacheDetection: true,
  cacheDuration: 300, // 5 minutes
});

React Hooks

useAgentDetection

Monitor detection status in your components:

import { useAgentDetection } from '@kya-os/agentshield-nextjs';

function Component() {
  const {
    isAgent,        // Boolean: detected as agent
    confidence,     // Number: confidence score (0-1)
    signals,        // Object: detection signals
    isLoading,      // Boolean: detection in progress
    error,          // Error: detection error if any
    refetch,        // Function: re-run detection
  } = useAgentDetection();
  
  if (isAgent && confidence > 0.9) {
    return <BlockedContent />;
  }
  
  return <NormalContent />;
}

useAgentShield

Access the full AgentShield client:

import { useAgentShield } from '@kya-os/agentshield-nextjs';

function Component() {
  const shield = useAgentShield();
  
  const handleSensitiveAction = async () => {
    const result = await shield.verify();
    
    if (result.isAgent) {
      alert('This action is not available');
      return;
    }
    
    // Proceed with sensitive action
  };
  
  return (
    <button onClick={handleSensitiveAction}>
      Sensitive Action
    </button>
  );
}

Edge Runtime Optimization

AgentShield is fully optimized for Next.js Edge Runtime, providing ultra-fast detection at the edge.

Edge API Routes

// app/api/protected/route.ts
import { NextRequest } from 'next/server';

export const runtime = 'edge';

export async function GET(request: NextRequest) {
  const detection = request.headers.get('x-agentshield-detection');
  
  if (detection) {
    const result = JSON.parse(detection);
    if (result.isAgent) {
      return new Response('Forbidden', { status: 403 });
    }
  }
  
  return new Response('Protected data');
}

Edge Middleware

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { agentShield } from '@kya-os/agentshield-nextjs';

export const runtime = 'edge';

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  onAgentDetected: 'block',
});

Session Tracking

Track AI agents across multiple requests:

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  
  sessionTracking: {
    enabled: true,
    storage: 'cookie',      // Use cookies for session storage
    duration: 86400000,     // 24 hour sessions
    
    // Optional: Custom session ID generator
    generateId: () => crypto.randomUUID(),
    
    // Optional: Session data enrichment
    enrichSession: (session) => ({
      ...session,
      timestamp: Date.now(),
      region: process.env.VERCEL_REGION,
    }),
  },
});

Custom Response Strategies

Challenge Page

customHandler: async (req, result) => {
  if (result.confidence > 0.7) {
    // Redirect to challenge page
    const challengeUrl = new URL('/challenge', req.url);
    challengeUrl.searchParams.set('return', req.nextUrl.pathname);
    return NextResponse.redirect(challengeUrl);
  }
  return NextResponse.next();
}

Rate Limiting

customHandler: async (req, result) => {
  if (result.isAgent) {
    // Apply rate limiting for detected agents
    const ip = req.ip || req.headers.get('x-forwarded-for');
    const rateLimitKey = `agent_${ip}`;
    
    const limited = await checkRateLimit(rateLimitKey);
    if (limited) {
      return new Response('Too Many Requests', { status: 429 });
    }
  }
  return NextResponse.next();
}

A/B Testing

customHandler: async (req, result) => {
  if (result.isAgent && result.confidence > 0.6) {
    // A/B test different responses
    const variant = Math.random() > 0.5 ? 'A' : 'B';
    
    if (variant === 'A') {
      return new Response('Access Restricted', { status: 403 });
    } else {
      return NextResponse.redirect(new URL('/limited', req.url));
    }
  }
  return NextResponse.next();
}

Monitoring & Analytics

Custom Logging

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  onAgentDetected: 'log',
  
  // Custom logging
  onDetection: async (result) => {
    // Send to your analytics
    await fetch('/api/analytics', {
      method: 'POST',
      body: JSON.stringify({
        event: 'agent_detected',
        ...result,
      }),
    });
  },
});

Vercel Analytics Integration

import { track } from '@vercel/analytics';

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  
  onDetection: async (result) => {
    if (result.isAgent) {
      track('agent_detected', {
        confidence: result.confidence,
        userAgent: result.signals.userAgent,
      });
    }
  },
});

Troubleshooting

Common Issues

Content Security Policy (CSP) Errors

If you're using the pixel.js and seeing errors like:

Refused to load the script 'https://kya.vouched.id/pixel.js' 
because it violates the following Content Security Policy directive

Solution: Add AgentShield domains to your CSP headers:

// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: [
              "default-src 'self'",
              "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://kya.vouched.id https://agentshield.io",
              "connect-src 'self' https://kya.vouched.id https://agentshield.io",
              "img-src 'self' data: https:",
              "style-src 'self' 'unsafe-inline'",
            ].join('; ')
          }
        ]
      }
    ]
  }
}

Alternative Solutions:

  1. Proxy the script through your API routes
  2. Self-host the pixel script (requires manual updates)
  3. Use middleware to dynamically add CSP headers

See our Pixel documentation for detailed CSP configuration instructions.

Middleware not running

  • Ensure middleware.ts is in the project root
  • Check the matcher configuration
  • Verify the file exports a default function

Detection not working

  • Verify API key is correct
  • Check network tab for API calls
  • Enable debug mode for detailed logs
  • If using pixel.js, check browser console for CSP errors

Performance issues

  • Enable caching with cacheDetection: true
  • Adjust confidenceThreshold if too sensitive
  • Use skipPaths for non-critical routes

Debug Mode

Enable detailed logging:

export default agentShield({
  apiKey: process.env.AGENTSHIELD_API_KEY!,
  debug: true,
  logLevel: 'debug',
});

Check console for:

  • Detection results
  • API responses
  • Performance metrics
  • Error messages

Best Practices

  1. Use Environment Variables - Never hardcode API keys
  2. Configure Matchers - Only protect necessary routes
  3. Enable Caching - Reduce API calls with caching
  4. Monitor Performance - Track middleware overhead
  5. Test Thoroughly - Test with various user agents
  6. Handle Errors - Implement fallback strategies
  7. Respect Privacy - Follow GDPR guidelines

Next Steps

Command Palette

Search for a command to run...