Nuxt rules

The full @geoql/oxlint-plugin-nuxt-doctor rule catalogue. ai-slop, data-fetching, hydration, server-routes.

The Nuxt plugin ships 10 rules across four categories. It is loaded by @geoql/nuxt-doctor automatically; you do not need to register it. The Vue plugin is also loaded — every Vue rule still applies.

ai-slop

Same idea as the Vue plugin: patterns that AI agents reach for because they look right in a chat, not because they work in Nuxt.

rule idseveritywhat it catches
no-fetch-in-setupwarnawait fetch(...) at the top of <script setup>
no-useState-for-server-dataerroruseState() to hold data that came from the server
no-explicit-imports-of-auto-importedwarnimporting things Nuxt already auto-imports
no-process-client-serverwarnprocess.client / process.server (Nuxt 3 syntax)

no-useState-for-server-data is the most-graded rule in the Nuxt set. It catches the AI habit of dropping server payloads into useState() so the template can react to them — except the data was the server payload, so the reactivity is wrong by construction.

data-fetching

Nuxt's data primitives are deceptively similar. useFetch, useAsyncData, $fetch, and useState all return refs, but only two of them carry SSR-aware hydration. The doctor flags the cases where the model picked the wrong one.

rule idseveritywhat it catches
useAsyncData-key-required-in-loopwarnuseAsyncData() inside a v-for without a key

The key collision in a loop is the bug — every iteration of the v-for would otherwise share the same payload, and the last iteration wins. The fix is always to derive a stable key from the loop variable.

hydration

Hydration mismatches are the AI-agent's favorite way to ship a "works locally, breaks in production" bug. The doctor is strict about anything that touches the DOM during SSR.

rule idseveritywhat it catches
no-document-in-setuperrordocument.* access inside <script setup>
clientOnly-for-browser-apiswarnwindow.*, localStorage.*, etc. without <ClientOnly>

no-document-in-setup is non-negotiable. document does not exist on the server, and the failure mode is a ReferenceError that crashes the entire SSR pass. The doctor emits this at error so it gates the default --fail-on error CI run.

server-routes

Nuxt's server/api/ directory is the easiest place for AI agents to introduce subtle security holes. The doctor flags them.

rule idseveritywhat it catches
validate-body-with-h3-v2warnreadBody() without a Zod schema or validator
defineEventHandler-typedwarndefineEventHandler() without an H3EventContext return type
createError-on-failurewarnbare throw new Error() in a server route

validate-body-with-h3-v2 is the rule you want running on every PR. An unvalidated request body is the single most common way a prompt-injection attack reaches your database.

Reading the rule list at runtime

You can dump the entire rule catalogue from the CLI:

bash
npx -y @geoql/nuxt-doctor list-rules

To filter:

by source
npx -y @geoql/nuxt-doctor list-rules --source oxlint
by category
npx -y @geoql/nuxt-doctor list-rules --category hydration
as JSON
npx -y @geoql/nuxt-doctor list-rules --json

To inspect a single rule:

bash
npx -y @geoql/nuxt-doctor explain no-useState-for-server-data

This prints the rule's description, severity, category, the source plugin, and the recommended fix.

What's not here

  • Build config validation (nuxt.config.ts correctness) — the doctor reads nuxt.config.ts for context but does not flag bad configuration. Use nuxt typecheck for that.
  • Module version mismatches — out of scope; use nuxi doctor or a real Renovate setup.
  • Performance benchmarks for server routes — the doctor is static; it does not run your handlers.