How to Block Bot Traffic in Nuxt With No Extra Infra

Nuxt server middleware + Nitro hooks give you bot-blocking primitives. Here's the production setup for self-hosted Nuxt 3.

May 9, 2026·5 min read

How to Block Bot Traffic in Nuxt With No Extra Infra

Nuxt 3 runs on Nitro. Bot blocking can happen at three layers: the SecureNow preload (Node-level), Nuxt server middleware (per-request), or a Nitro hook (event-level). Pick based on deployment target.

Self-hosted Nuxt: SecureNow preload

npm install securenow

# Update your start command:
node -r securenow/register .output/server/index.mjs

A known-bad IP feed refreshed hourly, plus your own blocklist, full Nuxt protection.

Nuxt server middleware

// server/middleware/firewall.ts
export default defineEventHandler((event) => {
  const ip = getRequestHeader(event, 'x-forwarded-for')?.split(',')[0]?.trim()
    || getRequestIP(event)
    || '';
  const ua = getRequestHeader(event, 'user-agent') || '';

  const GOOD_BOTS = /googlebot|bingbot|gptbot|claudebot|perplexitybot/i;
  const BAD_UA = /sqlmap|nikto|acunetix|masscan|python-requests/i;
  const BLOCKED_IPS = new Set(['185.220.101.42']);

  if (GOOD_BOTS.test(ua)) return;
  if (BLOCKED_IPS.has(ip)) {
    setResponseStatus(event, 403);
    return 'Forbidden';
  }
  if (BAD_UA.test(ua)) {
    setResponseStatus(event, 403);
    return 'Forbidden';
  }
});

This runs on every request before route handlers. Workable for static blocklists; for a feed refreshed hourly the preload is more practical.

Vercel-deployed Nuxt

Vercel runs Nuxt on serverless functions. The Node preload approach doesn't apply. Use server middleware with a Vercel KV-backed dynamic blocklist:

// server/middleware/firewall.ts
import { kv } from '@vercel/kv';

export default defineEventHandler(async (event) => {
  const ip = getRequestHeader(event, 'x-forwarded-for')?.split(',')[0]?.trim() || '';
  const blocked = await kv.sismember('blocklist:ips', ip);
  if (blocked) {
    setResponseStatus(event, 403);
    return 'Forbidden';
  }
});

Refresh blocklist:ips via a cron job pulling from a threat-intel feed.

Combining with Nuxt rate limiting

There's no first-party Nuxt rate-limit module; use h3's primitives or a shared store like Upstash Redis. See the Nuxt rate-limiting post for details.

Verifying

npx securenow firewall status

Frequently Asked Questions

Does Nuxt 3 use Nitro?

Yes. Nuxt 3's server engine is Nitro, which is also the engine for h3 / Nitro standalone. Hooks and middleware patterns are the same.

Can I use the SecureNow preload with Nuxt?

Yes for self-hosted Nuxt. Add `-r securenow/register` to your Node start command. For Vercel-deployed Nuxt, use server middleware instead.

What's the difference between server/middleware and Nitro plugins?

server/middleware runs per-request; Nitro plugins run once at startup. Use server/middleware for IP blocking, Nitro plugins for setting up shared state.

Recommended reading

Block an IP, a Range or One Route Without a Deploy (Node.js)

Block one IP, a CIDR range, or a single route and method in a Node.js app within seconds, with no code change: setup, scoping, CLI, MCP, verification and undo.

Oct 27
11 Signs Your AI-Built App Needs a Security Audit

Built your app with a coding agent? 11 warning signs it needs a security audit, each checkable in five minutes, and how to run the full audit yourself.

Oct 26
AI Security Audit Part 1: Set Up Your Agent to Audit Code

Part 1 of the AI security audit series: set up an AI coding agent to audit your app locally, connect SecureNow, and run your first threat-model pass.

Jul 24