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.

Lhoussine
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

500k IPs blocked, hourly refresh, automatic Googlebot/GPTBot allowlist, 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 500k entries 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

Related

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

Adding Backend Tracing to a Sentry Stack with OpenTelemetry

If your team uses Sentry for frontend errors and needs backend distributed tracing without doubling the Sentry bill, here's the OpenTelemetry path that doesn't make you choose.

May 9
How to Block Bot Traffic in Express With No Extra Infra

Five approaches to bot blocking in Express, ranked by effort vs. effectiveness. From a 5-line allowlist to a full IP-reputation firewall — all without Cloudflare, AWS WAF, or any new infrastructure.

May 9
How to Block Bot Traffic in Fastify With No Extra Infra

Fastify hooks (onRequest) and the SecureNow preload both work cleanly. Here's the production setup for IP blocking and user-agent filtering.

May 9