Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
2.0 KiB
Markdown
92 lines
2.0 KiB
Markdown
# Suspense Slots Only Allow One Immediate Child
|
|
|
|
## Rule
|
|
|
|
Both `#default` and `#fallback` slots of `<Suspense>` only allow for one immediate child node. Multiple root elements will cause unexpected behavior.
|
|
|
|
## Why This Matters
|
|
|
|
Vue's Suspense needs to track a single root node to manage the pending/resolved state transitions. Multiple children in the default slot can cause rendering issues or the Suspense to not work correctly.
|
|
|
|
## Bad Code
|
|
|
|
```vue
|
|
<template>
|
|
<!-- Multiple children in default slot - problematic -->
|
|
<Suspense>
|
|
<AsyncHeader />
|
|
<AsyncContent />
|
|
<AsyncFooter />
|
|
|
|
<template #fallback>
|
|
<LoadingHeader />
|
|
<LoadingContent />
|
|
</template>
|
|
</Suspense>
|
|
</template>
|
|
```
|
|
|
|
## Good Code
|
|
|
|
```vue
|
|
<template>
|
|
<!-- Single root wrapper in each slot -->
|
|
<Suspense>
|
|
<div class="page-container">
|
|
<AsyncHeader />
|
|
<AsyncContent />
|
|
<AsyncFooter />
|
|
</div>
|
|
|
|
<template #fallback>
|
|
<div class="loading-container">
|
|
<LoadingHeader />
|
|
<LoadingContent />
|
|
</div>
|
|
</template>
|
|
</Suspense>
|
|
</template>
|
|
```
|
|
|
|
## Alternative: Dedicated Layout Component
|
|
|
|
```vue
|
|
<!-- PageLayout.vue - Contains all async components -->
|
|
<script setup>
|
|
import AsyncHeader from './AsyncHeader.vue'
|
|
import AsyncContent from './AsyncContent.vue'
|
|
import AsyncFooter from './AsyncFooter.vue'
|
|
</script>
|
|
|
|
<template>
|
|
<div class="page-layout">
|
|
<AsyncHeader />
|
|
<AsyncContent />
|
|
<AsyncFooter />
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
```vue
|
|
<!-- Usage -->
|
|
<template>
|
|
<Suspense>
|
|
<PageLayout />
|
|
<template #fallback>
|
|
<SkeletonLayout />
|
|
</template>
|
|
</Suspense>
|
|
</template>
|
|
```
|
|
|
|
## Key Points
|
|
|
|
1. Always wrap multiple elements in a single container element
|
|
2. This applies to both `#default` and `#fallback` slots
|
|
3. Consider extracting complex layouts into dedicated components
|
|
4. The single-child requirement helps Vue track the component tree correctly
|
|
|
|
## References
|
|
|
|
- [Vue.js Suspense Documentation](https://vuejs.org/guide/built-ins/suspense)
|