Nostics
Recipes

Diagnostic registry

Publish stable docs pages for diagnostic codes.

A diagnostic code is most useful when it points to a page that explains the problem and the fix.

The page does not need to be long. It needs to be stable, readable without JavaScript, and consistent across codes.

Pick the URL shape

Use docsBase to decide where code pages live. A function gives you full control over the URL.

defineDiagnostics({
  docsBase: code => `https://nuxt.com/e/${code.replace('NUXT_', '').toLowerCase()}`,
  codes: {
    NUXT_B2011: { why: 'Plugin mode conflicts with file suffix.' },
  },
})

This creates https://nuxt.com/e/b2011.

Once published, keep the URL working. Logs and search results can outlive the release that emitted them.

Page template

# NUXT_B2011: Plugin mode conflicts with file suffix

Code: `NUXT_B2011`
Level: error

## What happened

Nuxt tried to register a plugin whose filename says it should run on one side, but whose `mode` says it should run on the other side.

## How to fix it

Remove `mode` and let the filename suffix decide:

```ts [app/plugins/analytics.server.ts]
export default defineNuxtPlugin(() => {
  // plugin code
})
```

## Common causes

- A plugin file was renamed from `.client.ts` to `.server.ts` without updating `mode`.
- A module option switches the plugin mode but not the resolved file path.
- A shared helper applies a default `mode` after the plugin path was already selected.

## Example output

```txt
[NUXT_B2011] Plugin `./runtime/analytics.server.ts` is server-only but was registered with mode `client`.
├▶ fix: Rename the file or register it with mode `server`.
╰▶ see: https://nuxt.com/e/b2011
```

Keep the fix near the top. Most people arrive from an error message and want the next action.

Keep it in sync

The useful rule is simple: a new published code should ship with its docs page.

Common ways to enforce that:

  • Keep the markdown in the same repo as the diagnostic catalog.
  • Generate an index of all codes from the catalog.
  • Add a CI check that every code has a matching page.

Example check:

import { existsSync } from 'node:fs'
import { diagnostics } from '../src/diagnostics'

const missing = Object.keys(diagnostics).filter((code) => {
  return !existsSync(`docs/errors/${code.toLowerCase()}.md`)
})

if (missing.length > 0) {
  console.error('Missing diagnostic docs:', missing.join(', '))
  process.exit(1)
}

Make pages easy to consume

  • Render the content in the initial HTML.
  • Include the code in the title and body.
  • Use the same section names on every page.
  • Keep examples self-contained.
  • Return 404 for unknown codes.

This helps humans, search engines, and tools that fetch the URL from a log.

Copyright © 2026