Bug tracking for Vue — session replay, console + HAR (2026)
3 min read · JavaScript
What Vue teams ship with BugMojo
Vue 3 reactivity is elegant when it works and quietly wrong when it does not. The most common bugs in Vue apps fall into two buckets: reactivity bugs (you mutated a ref directly, you destructured a reactive object, you assigned a new array instead of mutating in place) and lifecycle bugs (you set up a watcher and forgot to stop it, you read `$refs` before the component mounted). Neither shows up in a screenshot.
A useful Vue bug report includes the component name (because Vue's dev tools surface a tree, not a tag soup), the reactive state at the moment the user noticed the bug, and the network payload that triggered the reactive update. BugMojo captures the DOM + console + network — and Vue's dev-mode warnings are loud, so the report usually carries the answer in the console.
This guide is the practical bug-reporting handbook for Vue teams in 2026 — Composition API, `<script setup>`, Pinia, and Nuxt.
Vue gotchas
Framework-specific failure modes our team has shipped through. Each one is hard to spot in a screenshot — easy to spot in a session replay.
Destructuring a reactive object breaks reactivity
High impactA `const { user } = reactive({ user: {} })` extracts `user` as a plain object — the reactive proxy stays behind. The fix is `toRefs()` when destructuring, or just don't destructure. Bug: UI does not update when `user` changes.
watch() with deep: true runs on every nested mutation
Medium impactCheap to write, expensive to run. A deep watcher on a large object re-runs for every nested change, even ones you do not care about. Bug: the page locks up while typing. Replay shows the input lag; profiler confirms the watcher firing 60×/second.
Async setup leaves the component blank if it throws
High impactTop-level await in `<script setup async>` makes the component suspense-able. An unhandled rejection results in a blank component, not an error boundary. Catch errors locally and render a fallback.
Pinia store mutations outside actions warn but persist
Medium impactVue 3 dev mode warns when you mutate a Pinia store from a component, but the mutation still happens. Bug: state diverges between page reloads. Always wrap mutations in actions.
Common Vue bugs
Real bug patterns from Vue apps, with the symptom you’ll see in a bug report and the fix that actually works.
Reactive Map / Set values do not trigger re-renders
- Symptom
- You add an entry to a `reactive(new Map())` and the UI does not update.
- Fix
- Vue 3.0–3.4 had partial Map/Set reactivity; 3.5+ fixes it but you must use `reactive()` not `ref()`. Upgrade if you are below 3.5, OR use a plain object keyed by string.
// ✅ Vue 3.5+
const cache = reactive(new Map<string, User>());
cache.set(id, user); // triggers re-renderTemplate ref is null on first render
- Symptom
- `templateRef.value` is null inside a function called from `onMounted`.
- Fix
- Refs are populated synchronously on mount, but ONLY for elements present on the initial render. For elements rendered conditionally, use `nextTick()` or `watch` on the condition.
const el = ref<HTMLDivElement | null>(null);
onMounted(async () => {
await nextTick();
el.value?.focus();
});v-model on a custom component does not update parent
- Symptom
- Typing in a child input does not update the parent's state.
- Fix
- The child must emit `update:modelValue` (or your custom prop name). In `<script setup>`, use `defineModel()` (Vue 3.4+).
Setup
# Install BugMojo from the Chrome Web Store — works on Vue 2 and Vue 3 appsBugMojo vs alternatives
The honest comparison — where BugMojo wins, and where another tool might serve you better.
| Capability | BugMojo | Vue DevTools alone |
|---|---|---|
| See what the user saw (replay) | ✅ | ❌ |
| Console + network capture | ✅ | ❌ |
| Reactive state at failure | ✅ (DOM state) | ✅ (live only) |
| Shareable bug report | ✅ one-click | ❌ |
| Wired into Jira/Linear | ✅ | ❌ |
Frequently asked questions
Sources
- Vue 3 reactivity in depth — vuejs.org (2025)

