All skills
hyf0 avatar

/vue-debug-guides

@a5fc891 official
by hyf0hyf0/vue-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/hyf0/vue-skills/vue-debug-guides

This session only. Nothing lands on disk.

referencein-dom-template-parsing-caveats.md

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

In-DOM Template Parsing Caveats

Impact: HIGH - When writing Vue templates directly in the DOM (not in .vue files), the browser's native HTML parser processes the template BEFORE Vue sees it. This causes three critical issues: case sensitivity problems, self-closing tag failures, and element placement restrictions.

These issues do NOT apply to Single-File Components (SFCs) or string templates where Vue's compiler handles parsing directly.

Task Checklist

  • Use kebab-case for component names in in-DOM templates
  • Use kebab-case for prop names in in-DOM templates
  • Use explicit closing tags (not self-closing) in in-DOM templates
  • Use is="vue:component-name" for components inside restricted elements
  • Prefer SFCs to avoid all in-DOM parsing issues

Issue 1: Case Insensitivity

HTML is case-insensitive. The browser lowercases everything before Vue sees it.

Incorrect (in-DOM template):

<!-- Browser converts to: <blogpost posttitle="hello"> -->
<BlogPost postTitle="hello" @updatePost="onUpdate"></BlogPost>

Correct (in-DOM template):

<!-- Use kebab-case for everything -->
<blog-post post-title="hello" @update-post="onUpdate"></blog-post>

In SFCs, PascalCase works fine:

<!-- BlogPost.vue - PascalCase recommended -->
<template>
  <BlogPost postTitle="hello" @updatePost="onUpdate" />
</template>

Issue 2: Self-Closing Tags Fail

HTML only allows self-closing syntax for void elements (<input>, <img>, etc.). For all others, the browser expects closing tags.

Incorrect (in-DOM template):

<!-- Browser thinks the tag never closed, breaks nesting -->
<my-component />
<another-component />

Correct (in-DOM template):

<!-- Explicit closing tags required -->
<my-component></my-component>
<another-component></another-component>

In SFCs, self-closing works fine:

<template>
  <MyComponent />
  <AnotherComponent />
</template>

Issue 3: Element Placement Restrictions

Some HTML elements have strict rules about valid children. Invalid elements are hoisted out by the browser before Vue sees the template.

Restricted parent elements:

  • <ul>, <ol> - only allow <li>
  • <table> - only allows <thead>, <tbody>, <tfoot>, <tr>, <caption>, <colgroup>
  • <tr> - only allows <td>, <th>
  • <select> - only allows <option>, <optgroup>

Incorrect (in-DOM template):

<!-- Browser hoists blog-post-row outside the table -->
<table>
  <blog-post-row v-for="post in posts" :post="post"></blog-post-row>
</table>

<!-- Renders as: -->
<blog-post-row></blog-post-row>
<blog-post-row></blog-post-row>
<table></table>

Correct (in-DOM template):

<!-- Use is="vue:component-name" on a valid native element -->
<table>
  <tr is="vue:blog-post-row" v-for="post in posts" :key="post.id" :post="post"></tr>
</table>
<ul>
  <li is="vue:todo-item" v-for="todo in todos" :key="todo.id" :todo="todo"></li>
</ul>

Important: The vue: prefix is required! Without it, is is treated as a native customized built-in element attribute.

<!-- WRONG: Missing vue: prefix -->
<tr is="blog-post-row"></tr>

<!-- CORRECT: With vue: prefix -->
<tr is="vue:blog-post-row"></tr>

When Do These Apply?

Template Type Affected? Example
Single-File Component (.vue) No <template> section
String template No template: '<div>...</div>'
In-DOM template Yes <div id="app">...</div>
<script type="text/x-template"> Yes Browser parses the script content

Best Practice: Use SFCs

The simplest solution is to use Single-File Components (.vue files) which completely avoid in-DOM parsing issues:

<!-- MyComponent.vue - All issues avoided -->
<script setup>
import BlogPost from './BlogPost.vue'
</script>

<template>
  <BlogPost postTitle="hello" @updatePost="onUpdate" />

  <table>
    <BlogPostRow v-for="post in posts" :key="post.id" :post="post" />
  </table>
</template>

Reference

Source: SKILL.md on GitHub

No alerts17d5 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 files scanned · No issues

  • 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 hyf0/vue-skills/vue-debug-guides

Guides for diagnosing and fixing Vue 3 runtime errors, reactivity bugs, async failures, and hydration issues across components, templates, watchers, forms, and lifecycle hooks. Covers specific failure modes like stale watchers, ref unwrapping edge cases, v-model sync problems, and SSR mismatches with concrete reference links for each issue.

Generated from the current SKILL.md.

Does this skill cover Vue 2?
No. This skill is specific to Vue 3 debugging and error handling.
What should I use for Vue development best practices instead of debugging?
The skill references a separate `vue-best-practices` skill for development best practices and common gotchas.
Does this cover SSR and hydration issues?
Yes. The skill includes guides for diagnosing and fixing SSR rendering differences and hydration bugs.
Can this help with async watcher and watchEffect problems?
Yes. The skill covers async operation stale data, dependency tracking after await, and proper flush timing for watchers.
Does this address v-model and form-related issues?
Yes. The skill includes guides for v-model initial values, textarea interpolation, IME composition, and custom checkbox form submission.

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