Files
agent-skills/skills/vue-best-practices/reference/suspense-nested-suspensible-prop.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
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>
2026-02-16 16:27:42 -06:00

3.8 KiB

Use suspensible Prop for Nested Suspense (Vue 3.3+)

Rule

When nesting <Suspense> components, use the suspensible prop on the inner Suspense to properly coordinate with the parent Suspense. Without this prop, nested async components may render empty nodes until resolved instead of showing fallback content.

Why This Matters

Without the suspensible prop, the inner <Suspense> is treated as a synchronous component by the parent. This causes:

  • Empty nodes appearing briefly during async resolution
  • Multiple patching cycles as the component tree updates
  • Inconsistent loading states that confuse users

Bad Code

<template>
  <Suspense>
    <component :is="DynamicAsyncOuter">
      <!-- DynamicAsyncInner renders EMPTY until resolved! -->
      <component :is="DynamicAsyncInner" />
    </component>

    <template #fallback>
      Loading...
    </template>
  </Suspense>
</template>
<template>
  <Suspense>
    <OuterLayout>
      <!-- Inner Suspense not coordinated with parent -->
      <Suspense>
        <AsyncWidget />
        <template #fallback>Loading widget...</template>
      </Suspense>
    </OuterLayout>

    <template #fallback>
      Loading layout...
    </template>
  </Suspense>
</template>

Good Code

<template>
  <Suspense>
    <component :is="DynamicAsyncOuter">
      <!-- Inner Suspense with suspensible prop -->
      <Suspense suspensible>
        <component :is="DynamicAsyncInner" />
        <template #fallback>
          <InnerLoadingState />
        </template>
      </Suspense>
    </component>

    <template #fallback>
      <OuterLoadingState />
    </template>
  </Suspense>
</template>

Complex Layout Example

<template>
  <Suspense>
    <DashboardLayout>
      <template #sidebar>
        <!-- Sidebar has its own Suspense boundary -->
        <Suspense suspensible>
          <AsyncSidebar />
          <template #fallback>
            <SidebarSkeleton />
          </template>
        </Suspense>
      </template>

      <template #main>
        <!-- Main content has its own Suspense boundary -->
        <Suspense suspensible>
          <AsyncMainContent :key="contentKey" />
          <template #fallback>
            <ContentSkeleton />
          </template>
        </Suspense>
      </template>

      <template #widgets>
        <!-- Each widget can load independently -->
        <Suspense suspensible>
          <AsyncWidgets />
          <template #fallback>
            <WidgetsSkeleton />
          </template>
        </Suspense>
      </template>
    </DashboardLayout>

    <template #fallback>
      <FullPageLoader />
    </template>
  </Suspense>
</template>

How suspensible Works

Configuration Behavior
No suspensible prop Inner Suspense treated as sync; parent doesn't wait for inner async deps
suspensible on inner Inner async deps bubble up to parent Suspense for coordinated loading

When to Use Nested Suspense

Use nested Suspense with suspensible when:

  • Different page sections should show their own loading states
  • You want granular control over which parts show loading indicators
  • Sections can load at different speeds and should update independently

Avoid nested Suspense when:

  • A single loading state for the whole component is sufficient
  • The complexity isn't worth the UX benefit
  • You're targeting Vue versions before 3.3

Key Points

  1. Always add suspensible prop when nesting Suspense components
  2. Without suspensible, expect empty nodes and multiple patching cycles
  3. This feature requires Vue 3.3 or later
  4. Use nested Suspense boundaries strategically for better UX, not everywhere
  5. Each Suspense can have its own fallback for section-specific loading states

References