Adding an IP Firewall to Nuxt Without Cloudflare
On self-hosted Nuxt the SecureNow preload works. On Vercel-deployed Nuxt, server middleware + Vercel KV gives you the same outcome.
Adding an IP Firewall to Nuxt Without Cloudflare
Nuxt 3 deploys in many ways — Node, Vercel, Cloudflare Workers, AWS Lambda. The right firewall approach depends on which runtime your code actually executes in.
Self-hosted Nuxt (Node runtime)
npm install securenow
# In your start command:
node -r securenow/firewall-only .output/server/index.mjs
500k IPs blocked, hourly refresh, automatic crawler allowlisting. The standard recommendation.
For full SecureNow:
node -r securenow/register .output/server/index.mjs
Adds tracing, log capture, and AI investigation.
Vercel-deployed Nuxt
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()
|| getRequestIP(event)
|| '';
if (!ip) return;
const blocked = await kv.sismember('blocklist:ips', ip);
if (blocked) {
setResponseStatus(event, 403);
return 'Forbidden';
}
});
Refresh the blocklist via a cron job:
// server/api/cron/refresh-blocklist.ts
export default defineEventHandler(async (event) => {
const auth = getRequestHeader(event, 'authorization');
if (auth !== `Bearer ${process.env.CRON_SECRET}`) {
setResponseStatus(event, 401);
return 'Unauthorized';
}
const ips = await fetchAbuseipdbBlocklist(); // your fetch logic
await kv.del('blocklist:ips');
await kv.sadd('blocklist:ips', ...ips);
return `Refreshed ${ips.length} IPs`;
});
Schedule in vercel.json:
{
"crons": [{ "path": "/api/cron/refresh-blocklist", "schedule": "0 * * * *" }]
}
Cloudflare Workers / other edge runtimes
Replace Vercel KV with the runtime-appropriate store:
- Cloudflare Workers: Workers KV
- Deno Deploy: Deno KV
- Other edge platforms: Upstash Redis (HTTP-accessible)
The middleware logic is identical; only the store imports change.
Combining with rate limiting
Layer the rate-limit middleware (see the rate-limiting post) on top. The firewall blocks reputation-based; rate limiting handles per-IP request budgets.
Verifying
For self-host:
npx securenow firewall status
For Vercel KV-backed:
curl -i https://yourapp.com/ -H "X-Forwarded-For: 185.220.101.42"
# Expect: 403 Forbidden if IP is in blocklist
Related
Frequently Asked Questions
Does the SecureNow preload work on Vercel-deployed Nuxt?
No — Vercel runs your Nuxt code on serverless functions where Node preload flags don't apply. Use server middleware with a Vercel KV-backed dynamic blocklist instead.
What about Nitro's built-in deployment targets (Cloudflare Workers, etc.)?
Same logic as Vercel — you can't preload a Node module on edge runtimes. Use server middleware with a runtime-compatible store (Cloudflare KV, Workers KV, or HTTP-accessible Redis like Upstash).
Can I customize the blocklist?
Yes — add per-app rules from the SecureNow dashboard, CLI, or API. Custom rules sync to running SDK instances within ~10 seconds.
Recommended reading
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 9Five 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 9Fastify hooks (onRequest) and the SecureNow preload both work cleanly. Here's the production setup for IP blocking and user-agent filtering.
May 9