Getting Started with SecureNow and Nuxt 3 — Add Security Monitoring in Under 2 Minutes

A hands-on walkthrough for adding security observability to a Nuxt 3 app using the securenow npm package and official Nuxt module. Covers installation, nuxt.config.ts setup, environment variables, optional tuning, deployment targets, CLI verification, and troubleshooting.

Lhoussine
Apr 2, 2026·7 min read

Getting Started with SecureNow and Nuxt 3 — Add Security Monitoring in Under 2 Minutes

Modern Nuxt 3 applications are not “just frontends.” With Nitro, you ship API routes, server middleware, authentication callbacks, webhooks, and SSR HTML from the same codebase. Every one of those server entry points is a place where abuse can start: credential stuffing against /api/auth, SQL injection in query parameters, scanners probing for /.env, or bots hammering SSR pages to burn CPU. Traditional front-end analytics will not tell you what happened on the server before your page was sent.

SecureNow turns OpenTelemetry traces from your Nuxt server into a security-aware observability stream: you see who hit what, how fast it failed or succeeded, which headers were present, and (when enabled) redacted bodies for mutating requests — without building a custom logging pipeline or bolting a WAF onto every route by hand.

This guide is intentionally practical. You will install one npm package, add a single line to nuxt.config.ts, set two environment variables, and run nuxt dev. After that, we cover optional configuration, what is traced automatically, how to deploy to common hosts, how to confirm traces with the CLI, and what to do when something does not show up in the dashboard.

...

Why Nuxt 3 Apps Need Security Observability

Unified server surface. In Nuxt 3, “the server” is not a separate repo — it is Nitro: file-based API handlers, server routes, middleware, and SSR execution. A single compromised assumption in one handler can expose data from another. You need visibility that ties each incoming request to method, path, status, duration, and client context.

SSR amplifies risk. Server-side rendering executes your code for every page view. Attackers can craft URLs and headers that stress rendering paths, cache keys, or data-fetching logic. Without traces, you are guessing from CPU graphs.

API routes are public by default. Unless you lock everything behind auth, /api/* endpoints are discoverable. Observability lets you distinguish legitimate clients from scanning traffic and correlate spikes with specific paths and IPs.

Production parity. Development and production should send the same shape of telemetry (with sensible sampling if you choose). SecureNow uses OTLP over HTTP — the same integration pattern whether you run node .output/server/index.mjs, deploy to Vercel, or use Cloudflare.

...

Prerequisites

  • Node.js 18 or newer (LTS recommended; match what your host supports in production).
  • A Nuxt 3 project (nuxt >= 3.0.0). If you only have Nuxt 2, this module path is not applicable — upgrade or use a generic Node instrumentation path instead.
  • A terminal and browser for dashboard verification.
  • Optional but recommended: SecureNow CLI access (npx securenow) so you can create an application, log in, and run traces from the command line.

If you do not have a Nuxt app yet, scaffold one:

npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install
...

Step 1: Install securenow

From your project root:

npm install securenow

This package includes the OpenTelemetry SDK, Node auto-instrumentations, OTLP exporters, the SecureNow CLI entrypoint, and the Nuxt module re-exported as securenow/nuxt. You do not need to install @opentelemetry/* packages manually for the basic flow — the module externalizes them so Nitro does not incorrectly bundle OpenTelemetry internals.

If you use pnpm or yarn, the same dependency applies:

pnpm add securenow
# or
yarn add securenow
...

Step 2: Add the Module to nuxt.config.ts

Open nuxt.config.ts (or nuxt.config.js) and register the module:

export default defineNuxtConfig({
  modules: ['securenow/nuxt'],
});

That is the minimum required change. When the dev or production server starts, you should see a short log line indicating the module loaded and the Nitro server plugin was registered — more on that under verification.

If you already have other modules (Pinia, UI libraries, etc.), append 'securenow/nuxt' to the existing array:

export default defineNuxtConfig({
  modules: ['@pinia/nuxt', 'securenow/nuxt'],
});

TypeScript: Nuxt picks up the module without extra @types — the package ships integration metadata compatible with Nuxt 3’s module resolution.

...

Step 3: Set Environment Variables

Create or update a .env file in the project root (same level as nuxt.config.ts). At minimum you need:

SECURENOW_APPID=my-nuxt-app
SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
VariablePurpose
SECURENOW_APPIDIdentifies your application in the SecureNow dashboard — use a stable name (e.g. acme-storefront) or the UUID returned when you create an app via the CLI.
SECURENOW_INSTANCEBase URL of the OTLP-compatible collector. The free trial endpoint shown above accepts traces over HTTPS.

Getting real credentials from the CLI (recommended). If you have not created an app yet:

npx securenow login
npx securenow apps create my-nuxt-app

The CLI prints SECURENOW_APPID and SECURENOW_INSTANCE — paste them into .env. You can also create an application from the web dashboard and copy the same values.

Nuxt and .env: Nuxt loads .env automatically for the build and runtime. For hosted platforms, set these variables in the provider’s UI (Vercel, Cloudflare, etc.) — never commit secrets you do not intend to share.

...

Step 4: Start the App and Verify Traces Appear

Start the development server:

npx nuxt dev

Watch the terminal for lines similar to:

[securenow] Nuxt module loaded — server plugin registered
[securenow] 🚀 Nuxt OTel SDK started → https://freetrial.securenow.ai:4318/v1/traces
[securenow] service.name=my-nuxt-app instance.id=my-nuxt-app-...

If you see the SDK start message and a plausible service.name, the pipeline is live.

Generate traffic:

  • Open the app in the browser (SSR will emit spans).
  • Hit an API route if you have one, e.g. GET /api/health.
  • Use curl if you prefer:
curl -i http://localhost:3000/
curl -i http://localhost:3000/api/your-endpoint

Confirm in the product:

npx securenow status
npx securenow traces

You should see recent traces for your service. For a fuller view, open the SecureNow web app in the browser and filter by your SECURENOW_APPID.

...

Optional Configuration in nuxt.config.ts

The module accepts a securenow key for overrides. Common options:

export default defineNuxtConfig({
  modules: ['securenow/nuxt'],
  securenow: {
    serviceName: 'my-nuxt-app',   // overrides SECURENOW_APPID if set
    endpoint: 'https://...',      // overrides SECURENOW_INSTANCE
    noUuid: true,                 // single stable service.name (no UUID suffix)
    captureBody: true,            // attach POST/PUT/PATCH bodies (redacted)
    logging: true,                // forward console.* as OTLP logs
  },
});

captureBody

When true, mutating requests can include body payloads in telemetry (JSON, form-urlencoded, GraphQL, etc.). Sensitive fields are redacted using built-in rules; you can extend redaction with SECURENOW_SENSITIVE_FIELDS (comma-separated). Large bodies are skipped based on SECURENOW_MAX_BODY_SIZE (default 10240 bytes).

Enable this when you need forensic detail for abuse investigations — not every project needs it in development.

logging

When true, console.log, console.info, console.warn, console.error, and console.debug are forwarded as OpenTelemetry log records and correlated with active spans. This mirrors the Express flow where console instrumentation is separate — here it is a single module flag.

You can also use the environment variable SECURENOW_LOGGING_ENABLED=1 instead of or in addition to the config key, depending on how you manage environments.

noUuid

By default, a unique suffix may be appended so multiple local processes do not collide in the same dashboard view. In production — especially behind multiple instances — set noUuid: true or SECURENOW_NO_UUID=1 so all workers report under one logical service name, which makes dashboards and alerts easier to reason about.

Equivalent environment variables

For CI or hosts where you only control env vars:

EnvEffect
SECURENOW_CAPTURE_BODY=1Enable body capture
SECURENOW_LOGGING_ENABLED=1Enable console → OTLP logs
SECURENOW_NO_UUID=1Stable service name
SECURENOW_MAX_BODY_SIZEMax captured body size in bytes
OTEL_EXPORTER_OTLP_ENDPOINTAlternative OTLP base URL
OTEL_EXPORTER_OTLP_HEADERSk=v,k2=v2 style headers for the exporter
...

What Gets Traced Automatically

You do not need to wrap each handler. The Nitro server plugin and OpenTelemetry stack record:

  • All Nitro server handler requests — including dynamic API routes under /server/api (or your configured structure), server middleware, and SSR page requests that execute on the server.
  • HTTP semantics — method, path, status code, and duration.
  • Client IP — with proxy-aware resolution when X-Forwarded-For or similar headers are present (depends on your deployment; configure trusted proxies on the platform when applicable).
  • Headers — User-Agent, Referer, Origin, Host, and security-relevant auth/cookie/CSRF context where available.
  • Request IDs and correlation — when present, so you can tie logs and traces together across services.

With captureBody: true, mutating methods include redacted body snippets where allowed by size and content type.

With logging: true, your application logs show up alongside traces for the same request, which dramatically shortens incident triage.

...

Deployment

Node.js server (Docker, PM2, bare metal)

Build and run the standard Nitro output:

npx nuxt build
node .output/server/index.mjs

Set SECURENOW_APPID and SECURENOW_INSTANCE in the process environment or in a .env file loaded by your process manager. No extra preload flags are required — the module loads with Nuxt.

Vercel

Add SECURENOW_APPID and SECURENOW_INSTANCE in Project → Settings → Environment Variables for Production and Preview. Redeploy so the Nuxt build picks them up. Vercel runs your server in a Node-compatible runtime for SSR; tracing targets that server path.

Cloudflare / Netlify / other hosts

Set the same two variables in the provider dashboard. Note: Pure edge runtimes (e.g. some Workers-only modes) may not expose full Node APIs; Nitro server-handler tracing is intended for the Node server path. If your deployment splits edge vs Node, confirm where Nuxt executes your API routes and SSR — that is where SecureNow will see traffic.

For Cloudflare specifically, consult your host’s docs for Node compatibility layers; env var names remain the same.

...

Using the CLI to View Traces

After you log in once:

npx securenow login

List recent traces (uses your default app if configured):

npx securenow traces

Set a default application to avoid passing IDs every time:

npx securenow config set defaultApp YOUR_APP_ID

Other useful commands while debugging instrumentation:

CommandPurpose
npx securenow whoamiConfirm CLI auth
npx securenow statusHigh-level app / collector status
npx securenow traces show <traceId>Inspect one trace
npx securenow logsRecent log records if logging is enabled

The CLI is optional for sending telemetry — the module does that at runtime — but it is the fastest way to verify payloads without only relying on the browser.

...

Troubleshooting

No traces in the dashboard

  1. Confirm env varsSECURENOW_APPID and SECURENOW_INSTANCE must be set in the environment that runs nuxt dev or production node .output/server/index.mjs. Typos and missing https:// on the instance URL are common mistakes.
  2. Read startup logs — You should see [securenow] 🚀 Nuxt OTel SDK started and an OTLP URL. If the module loaded but the SDK did not start, check for errors immediately above.
  3. Network egress — From the machine or container, the OTLP endpoint must be reachable (firewall, corporate proxy, air-gapped CI). A quick test: curl -I to the host or run a one-off Node script that POSTs to /v1/traces (expect 405 or auth errors — anything but total connection failure).
  4. Wrong app — If you have multiple SECURENOW_APPID values, verify the dashboard filter matches the ID printed in logs.

Module does not load

  • Ensure Nuxt 3 (nuxt >= 3.0.0).
  • Put 'securenow/nuxt' in modules, not the deprecated buildModules for Nuxt 3.
  • Delete .nuxt and node_modules/.cache and restart after major upgrades.

Bundling or externals errors

The module adds OpenTelemetry packages to Nitro externals. If you still see bundling errors, merge additional externals manually:

export default defineNuxtConfig({
  modules: ['securenow/nuxt'],
  nitro: {
    externals: {
      external: ['securenow', '@opentelemetry/api', '@opentelemetry/sdk-node'],
    },
  },
});

Adjust the list to match the error message — the package README lists the full recommended set.

Traces only in dev, not production

  • Environment variables are often set for Development but not Production on the host — duplicate them.
  • Some platforms strip .env — use the host’s secret store.
  • If you use cluster or multiple replicas, consider noUuid: true so you are not hunting a random suffix per process.

Sensitive data concerns

If you enabled captureBody and worry about leakage, start with it off in production, enable only during incidents, or tighten SECURENOW_SENSITIVE_FIELDS. Logs with logging: true should avoid printing secrets in console.* — treat the log pipeline as security-sensitive.

...

Security Detections (What Happens After Traces Flow)

Once OTLP data reaches SecureNow, the platform can correlate traces with detection logic — for example unusual error rates on auth routes, suspicious patterns in parameters and bodies (when captured), and anomalous client behavior. Exact feature availability depends on your plan and configuration; the instrumentation goal is to give the backend enough structured context to reason about abuse without rewriting your Nuxt app.

...

Recap

StepActionRough time
1npm install securenowUnder a minute
2Add modules: ['securenow/nuxt']Seconds
3Set SECURENOW_APPID + SECURENOW_INSTANCEOne minute
4nuxt dev and hit a page or APIOne minute
OptionalTune captureBody, logging, noUuidAs needed

That is the full “under two minutes” path for someone who already has a Nuxt project and credentials; add a few more minutes if you are also creating the SecureNow app and logging in for the first time.

...

Next Steps

  • Explore traces and issues in the SecureNow web dashboard for your SECURENOW_APPID.
  • Set alert rules for critical paths (login, admin APIs, payment webhooks).
  • Use npx securenow traces during development to build intuition for what normal traffic looks like before you need it in an incident.
  • Read the package README on npm for the latest env vars and Nitro compatibility notes.

Happy shipping — and clear visibility into what your Nuxt server is actually doing.

Frequently Asked Questions

Do I need to wrap every API route or Nitro handler in custom middleware?

No. The securenow/nuxt module registers a Nitro server plugin that instruments server-side traffic automatically. You keep your existing routes, server middleware, and composables — no per-route boilerplate.

Does SecureNow trace client-side navigation and browser-only code?

The Nuxt integration focuses on server-side execution: Nitro handlers, SSR-rendered pages, and API routes. Client bundle code is not the primary signal for this module; security-relevant request metadata is captured where requests enter your server.

Can I use the same OTLP endpoint on Vercel, Cloudflare, and a plain Node server?

Yes — set SECURENOW_APPID and SECURENOW_INSTANCE in each environment’s dashboard. On edge-only runtimes some Node-specific instrumentations may be limited; Nitro server-handler tracing is still designed to work where your Nuxt server runs.

How do I avoid splitting traces across many random service names in production?

Set securenow.noUuid to true in nuxt.config.ts or SECURENOW_NO_UUID=1 in the environment so the reported service name stays stable (similar to clustered Node deployments).

Recommended reading

One Flag to Trace Them All — `-r securenow/register` Now Works for ESM and CJS

Stop juggling --require and --import flags. securenow/register now auto-registers the ESM loader hook via module.register() on Node >=20.6, so a single -r flag is all you need for both CommonJS and ESM apps.

Apr 2
Add Security Monitoring to a Next.js App with SecureNow — Traces, Logs, and Body Capture on AWS

Step-by-step guide to integrating SecureNow into a self-hosted Next.js application on AWS EC2. Covers installation, instrumentation, environment configuration, verifying traces and logs, enabling request body capture, and creating alert rules.

Mar 29
deploy nextjs hacker news aws securenow
How to Secure Your Fastify App with SecureNow — Real-Time API Protection via OpenTelemetry

Step-by-step guide to adding security monitoring to your Fastify API with the securenow npm package. Covers CLI setup, instrumentation, body capture caveats, PM2, Docker, and dashboard verification.

Mar 26
getting started securenow fastify