BugMojoBugMojoBugMojo
FeaturesPricingBlogGuidesAbout
Log inGet started
BugMojoBugMojo

Bug reports that actually help fix bugs — capture, replay, share.

A product of Softech Infra.

Product

  • Features
  • Pricing
  • Get started
  • Log in

Resources

  • Blog
  • Guides
  • Compare
  • Glossary

Company

  • About
  • Contact
  • Privacy
  • Sitemap
  • Engineering
  • Playbooks
© 2026 BugMojo. All rights reserved.
AllGuidesEngineeringPlaybooksCompareGlossaryAlternativesBy roleBug tracking by framework
  1. Home
  2. Blog
  3. Bug tracking by framework
  4. Nuxt 3
Bug tracking by framework

Bug tracking for Nuxt — session replay, console + HAR (2026)

Nuxt bug-reporting guide for QA + dev teams: framework-specific gotchas, common bugs, and how to capture them with BugMojo session replay.

6 min read·JavaScript
Isometric line-art browser showing a Nuxt server-versus-client hydration mismatch with a 500 Nitro request card peeling toward an IDE, lit by one lime glow

What Nuxt teams ship with BugMojo

Nuxt is the default meta-framework for Vue teams, and that universal SSR posture is exactly what makes its bug profile distinct from plain client-only Vue. The errors you will lose the most time to live on two boundaries: the hydration seam where server-rendered HTML meets client Vue, and the Nitro server layer where your /server/api routes run. Nuxt's own best-practices doc enumerates five mismatch causes by name — browser-only APIs like localStorage and window.innerWidth, non-deterministic values like Math.random(), time-dependent content like new Date(), invalid HTML nesting the browser silently repairs, and third-party libraries with DOM side effects — and prescribes ClientOnly, useCookie, CSS media queries, onMounted deferral, and the NuxtTime component as fixes.

A bug report from a Nuxt app needs three things a screenshot cannot give you. It needs the pre-hydration HTML and the instant client hydration took over, because the same render can differ between server and client. It needs the browser console, where Vue emits the exact '[Vue warn]: Hydration node mismatch' and '[Vue warn]: Hydration children mismatch' strings that name the offending subtree. And it needs the network HAR, because in Nitro any uncaught error returns a generic 500, and a real status only reaches the client if you throw createError with an explicit status. BugMojo records all three on demand, then exposes them to Claude Code or Cursor through an MCP server so an AI agent can triage the report inside your IDE.

Nuxt gotchas

Framework-specific failure modes engineers actually ship through. Each is hard to spot in a screenshot and obvious in a session replay.

Async-component hydration mismatches are silently not reported

nuxt/nuxt #23590 documents that a mismatch caused by an async component is not logged in dev OR prod: the mismatch check runs before deferred async hydration completes, so hasMismatch is still false and console.error never fires. The page can render visibly wrong while the console stays clean, which is a real observability gap. A DOM session replay of the actual render is often the only way to catch it.

$fetch to an external API can be intercepted during SSR

nitrojs/nitro #3953 shows that $fetch, ofetch, and native fetch are all intercepted by Nitro's internal routing during SSR, so an external call can 404 with 'No match found for location with path' even though curl reaches the same URL. The issue was closed as not planned. Capture the failing request to confirm whether it ever actually left the server.

createError behaves asymmetrically by environment

Thrown on the server, createError triggers a full-screen error page; thrown on the client it produces a NON-fatal error unless you pass fatal: true. The same helper therefore yields different UX depending on whether the code ran during SSR or after hydration. When a fatal SSR error meets an Accept: application/json request it returns JSON, otherwise a full-screen page.

Any uncaught error in a server route becomes a generic 500

In Nitro server routes 'any uncaught errors will return a 500 Internal Server Error', so the real cause is hidden behind a flat status. To surface a usable status you must throw createError({ status: 400, statusText: '...' }). statusText reaches the client; a plain message on an API route does not, which trips up teams who only set message.

You cannot define a server-side handler for Nitro errors

Nuxt's error-handling docs state you 'cannot currently define a server-side handler' for server/Nitro errors — you can only render an error.vue page. That means you cannot centrally rewrite a 500 the way you might expect; you handle it at the throw site with createError or in the rendered error page, and the report needs the raw response body to see what actually failed.

Common Nuxt bugs

Real Nuxt bug patterns — the symptom you will see in a report and the fix that actually works.

Hydration mismatch from browser-only or non-deterministic values

Symptom: Console shows '[Vue warn]: Hydration node mismatch' or 'Hydration children mismatch', text flickers on first paint, and Vue re-renders the affected subtree, hurting time-to-interactive and sometimes breaking event listeners.

Fix: Defer browser-only reads (localStorage, window.innerWidth) and non-deterministic values (Math.random(), new Date()) until the client. Use onMounted, wrap the node in <ClientOnly>, persist state with useCookie instead of localStorage, or render times with the NuxtTime component so server and client agree.

vuevue
<!-- ❌ runs on server AND client, values diverge -->
<span>{{ new Date().toLocaleTimeString() }}</span>

<!-- ✅ client-only, no mismatch -->
<ClientOnly>
  <span>{{ new Date().toLocaleTimeString() }}</span>
</ClientOnly>
<!-- or: <NuxtTime :datetime="Date.now()" /> -->

Server route returns a flat 500 instead of a usable status

Symptom: A /server/api route fails and the client only sees a generic 500 Internal Server Error with no actionable message, even though you know exactly what went wrong server-side.

Fix: Stop letting the error bubble. Throw createError with an explicit status and statusText, because statusText reaches the client while a plain message on an API route does not. The captured network HAR then shows the real status and the JSON error body for that request.

tsts
// server/api/users/[id].get.ts
export default defineEventHandler((event) => {
  const id = getRouterParam(event, 'id')
  if (!/^\d+$/.test(id ?? '')) {
    // ❌ throw new Error('bad id')  -> generic 500
    // ✅ typed status reaches the client
    throw createError({ status: 400, statusText: 'ID should be an integer' })
  }
})

External $fetch call 404s only during SSR

Symptom: An API call works in the browser and from curl, but the server-rendered request 404s with 'No match found for location with path' because Nitro's internal routing intercepted it.

Fix: Confirm the request actually left the server by inspecting the captured HAR. Use an absolute external URL, and when forwarding cookies/headers from the incoming request prefer event.$fetch so context is carried correctly rather than colliding with Nitro's internal route table.

tsts
// ❌ may be intercepted by Nitro routing during SSR
const data = await $fetch('/v1/widgets')

// ✅ absolute external origin
const data = await $fetch('https://api.example.com/v1/widgets')
// forwarding context from the event:
// const data = await event.$fetch('https://api.example.com/v1/widgets')

BugMojo vs alternatives

The honest comparison — where BugMojo wins, and where another tool might serve you better.

FeatureBugMojoSentry
On-demand rrweb DOM replay of the pre/post-hydration render✅ shows the mismatch flash even when the warning was suppressed⚠️ Session Replay (sampled, always-on)
Network HAR with the failing /server/api request + 500 / createError status✅ full request + response headers + JSON error body⚠️ server-side event view
Captures from SSR, SSG (nuxi generate) & hybrid routeRules uniformly✅ browser-layer, no Nitro plugin⚠️ needs SDK + Nitro instrumentation
MCP server: Claude Code / Cursor read the report in the IDE✅ bug is a first-class assignee❌ none
Always-on production error monitoring, aggregation & alerting❌ on-demand capture only✅ Sentry is more complete
Mature server-side error tracking & release health❌✅ Sentry
Console + network (HAR) capture✓Partial
Zero-setup Quick CaptureNo project, no SDKAccount / SDK required
The BugMojo column is highlighted. The closing rows are BugMojo’s core wedge: rrweb session replay, MCP for AI agents, console + network capture, and zero-setup Quick Capture.
Capture your next bug in 15 seconds

BugMojo records the DOM, console, and network — then ships a one-click ticket with the full replay attached. No SDK, no setup.

Try BugMojo free

Frequently asked questions

Frequently asked questions

Sources

  1. Nuxt 3 docs — Best Practices: Hydration (five named mismatch causes + ClientOnly/NuxtTime/useCookie remedies) — Nuxt (official docs, v3.x) (2025)
  2. Nuxt docs — server/ directory: uncaught errors return 500, createError with status, event.$fetch context forwarding — Nuxt (official docs) (2025)
  3. Nuxt docs — Error Handling: SSR fatal vs client non-fatal, error.vue, cannot define a server-side handler for Nitro errors — Nuxt (official docs) (2025)
  4. Nuxt createError util — fatal:true triggers full-screen page; statusText reaches the client (message does not for API routes) — Nuxt (official docs, v3.x) (2025)
  5. nitrojs/nitro #3953 — $fetch intercepted by internal routing during SSR; external API calls fail (closed as not planned) — GitHub — nitrojs/nitro (2024)
  6. nuxt/nuxt #23590 — hydration mismatch warning NOT shown when caused by an async component (closed as not planned) — GitHub — nuxt/nuxt (2024)
  7. Harlan Wilton — Nuxt 3 'Hydration Mismatch' Errors (exact [Vue warn] node/children mismatch strings) — harlanzw.com (Nuxt core team member) (2024)
  8. State of JS 2024 — Meta-Frameworks (Nuxt is the default Vue meta-framework; retention/usage rankings) — State of JavaScript 2024 (2025)
Share:

More frameworks

Pick another — each guide has its own gotchas, comparison, and fixes.

Next.js 15
JavaScript
Vue 3.5
JavaScript
SvelteKit 2 (Svelte 5)
JavaScript
React 19
JavaScript
WordPress
PHP / CMS
Angular 19
TypeScript

On this page

  • What Nuxt teams ship with BugMojo
  • Nuxt gotchas
  • Common Nuxt bugs
  • BugMojo vs alternatives