All skills
vuejs-ai avatar

/vue-debug-guides

@a5fc891 official
by Vue AIvuejs-ai/skills2.9k stars
167

Vue 3 debugging and error handling for runtime errors, warnings, async failures, and SSR/hydration issues. Use when diagnosing or fixing Vue issues.

Use this Skill: https://skilld.dev/gh/vuejs-ai/skills/vue-debug-guides

This session only. Nothing lands on disk.

referenceprovide-inject-debugging-challenges.md

≈1.4k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Provide/Inject Has Limited DevTools Support - Plan for Debugging

Impact: LOW - While provide/inject is powerful for avoiding prop drilling, it creates less visible data flow than props. Provided values are not as easily inspectable in Vue DevTools, and tracing where a value comes from requires navigating the component tree manually.

Task Checklist

  • Document provided values at the provider component level
  • Use descriptive Symbol descriptions for easier identification
  • Consider adding development-only logging for provided state changes
  • Keep provide/inject chains shallow when possible
  • Prefer Pinia for complex state that needs DevTools integration

The Challenge

Unlike props which are clearly visible in Vue DevTools for each component, provided values:

  1. Don't show which ancestor provided them
  2. Require manual navigation to find the provider
  3. Don't show in the standard props/data panels
  4. Can be shadowed by closer ancestors using the same key

Strategies for Better Debugging

1. Use Descriptive Symbol Names

// injection-keys.js

// BETTER: Descriptive names appear in errors and debugging
export const UserAuthKey = Symbol('UserAuthenticationState')
export const ThemeConfigKey = Symbol('ThemeConfiguration')
export const FormContextKey = Symbol('FormValidationContext')

// WORSE: Generic names are harder to trace
export const UserKey = Symbol()
export const ThemeKey = Symbol('theme')

2. Document Providers Clearly

<!-- AuthProvider.vue -->
<script setup>
/**
 * Authentication Provider
 *
 * Provides:
 * - UserAuthKey: Current user state (Ref<User | null>)
 * - AuthActionsKey: { login, logout, refresh }
 *
 * Must wrap any component that needs authentication state.
 */
import { provide, ref, readonly } from 'vue'
import { UserAuthKey, AuthActionsKey } from '@/injection-keys'

const user = ref(null)

// ... implementation

provide(UserAuthKey, readonly(user))
provide(AuthActionsKey, { login, logout, refresh })
</script>

3. Development-Only Logging

// composables/useProvideWithLogging.js
import { provide, watch, getCurrentInstance } from 'vue'

export function useProvideWithLogging(key, value, name) {
  provide(key, value)

  if (import.meta.env.DEV) {
    const instance = getCurrentInstance()
    const componentName = instance?.type?.name || 'Unknown'

    console.log(`[Provide] ${name} provided by <${componentName}>`)

    // Log reactive changes
    if (value && typeof value === 'object' && 'value' in value) {
      watch(value, (newVal) => {
        console.log(`[Provide] ${name} changed:`, newVal)
      }, { deep: true })
    }
  }
}
<script setup>
import { ref } from 'vue'
import { useProvideWithLogging } from '@/composables/useProvideWithLogging'
import { ThemeKey } from '@/injection-keys'

const theme = ref('dark')

// In development, logs when provided and when changed
useProvideWithLogging(ThemeKey, theme, 'Theme')
</script>

4. Inject with Missing Provider Warnings

// composables/useSafeInject.js
import { inject, getCurrentInstance } from 'vue'

export function useSafeInject(key, fallback, keyName) {
  const value = inject(key, undefined)

  if (value === undefined) {
    const instance = getCurrentInstance()
    const componentName = instance?.type?.name || 'Unknown'

    if (import.meta.env.DEV) {
      console.warn(
        `[Inject] ${keyName || String(key)} not provided. ` +
        `Component <${componentName}> is using fallback value. ` +
        `Ensure a provider exists in the ancestor chain.`
      )
    }

    return typeof fallback === 'function' ? fallback() : fallback
  }

  return value
}
<script setup>
import { useSafeInject } from '@/composables/useSafeInject'
import { ThemeKey } from '@/injection-keys'

// Warns in dev if no provider found
const theme = useSafeInject(ThemeKey, () => ({ mode: 'light' }), 'ThemeConfig')
</script>

5. Create Provider Registry for Complex Apps

// utils/provider-registry.js
const providerRegistry = new Map()

export function registerProvider(key, componentName, value) {
  if (import.meta.env.DEV) {
    providerRegistry.set(key, {
      componentName,
      value,
      timestamp: Date.now()
    })
  }
}

export function getProviderInfo(key) {
  return providerRegistry.get(key)
}

// For DevTools custom plugin or debugging
export function getAllProviders() {
  return Object.fromEntries(providerRegistry)
}

// Expose to window for console debugging
if (import.meta.env.DEV) {
  window.__VUE_PROVIDERS__ = {
    getAll: getAllProviders,
    get: getProviderInfo
  }
}

When to Use Pinia Instead

If you find yourself needing extensive debugging for state:

Use Provide/Inject Use Pinia
Component library internals Application-wide state
Theme/locale configuration User session data
Form context Shopping cart
Simple parent-child sharing Complex state with actions
Plugin configuration State that needs time-travel debugging

Pinia provides excellent DevTools integration with:

  • State inspection
  • Time-travel debugging
  • Action logging
  • Hot module replacement

Reference

Source: SKILL.md on GitHub

1 warning17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill is a comprehensive collection of educational debugging guides and best practices for Vue 3 developers. It contains no executable code or malicious instructions and focuses solely on diagnosing common runtime errors and performance issues.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    140/140 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at a5fc891. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 8 months ago

README badge

README badge for vuejs-ai/skills/vue-debug-guides

Guides for diagnosing Vue 3 runtime errors, reactivity bugs, component lifecycle issues, and SSR hydration problems. Covers reactivity traps (refs, computed, watchers), component mechanics (props, emits, slots), templates (v-if, v-for, refs), forms (v-model), and composition API gotchas.

Generated from the current SKILL.md.

Does this cover Vue 2 or only Vue 3?
This skill is for Vue 3 only. It addresses Vue 3-specific debugging patterns like reactivity proxies, script setup, and defineEmits/defineProps.
Does this skill help with performance optimization?
No. This skill focuses on runtime errors, warnings, and behavioral bugs. For development best practices and optimization, use the separate `vue-best-practices` skill.
What kinds of issues does this cover?
Reactivity traps (refs, computed, watchers), component lifecycle bugs, template directives, form binding edge cases, SSR/hydration mismatches, slot scoping, and async-related failures.
Does this include debugging for Nuxt or other Vue frameworks?
No. This skill focuses on core Vue 3 runtime issues. Framework-specific bugs are outside its scope.

Generated from the current SKILL.md. These answers refresh after source changes.