# Vue 3 Teleport and Suspense: Advanced Patterns and Interview Questions 2026
> Master Vue 3 Teleport for DOM portaling and Suspense for async rendering. Covers the new defer prop, nested Suspense patterns, and interview questions for 2026.
- Published: 2026-08-28
- Updated: 2026-08-28
- Author: Anthony Fillion-Maillet
- Tags: vue, vue3, teleport, suspense, interview
- Reading time: 9 min
---
Vue 3 Teleport and Suspense solve two distinct rendering challenges: placing components outside their DOM hierarchy and coordinating async dependencies. Both are built-in components that require no imports, and both come up frequently in senior Vue developer interviews.
> **Vue 3.5 Teleport Update**
>
> Vue 3.5 added the `defer` prop to Teleport, allowing targets rendered later in the component tree. This solves the common SSR timing issue where the portal target does not exist at mount time.
## Teleport Fundamentals and the defer Prop
Teleport moves rendered content to a different DOM location while preserving the Vue component tree. The component remains a logical child of its parent: props, events, and provide/inject all work normally. Vue DevTools shows the teleported component nested under its parent, not under the target element.
```vue
```
The `to` prop accepts a CSS selector string or a DOM element reference. When the target does not exist at mount time, Teleport throws a warning and renders nothing. This creates problems with SSR and dynamic layouts.
### The defer Prop (Vue 3.5+)
The `defer` prop tells Teleport to wait until other parts of the application have mounted before resolving the target. This enables teleporting to elements rendered later in the same component or in sibling components.
```vue
```
Without `defer`, this code fails because `#dynamic-target` does not exist when Teleport mounts. With `defer`, Vue resolves the target after all components in the same tick have mounted. The target must still render in the same mount or update cycle.
## Multiple Teleports and Conditional Rendering
Multiple Teleport components can target the same element. Content appends in declaration order:
```vue
```
The `disabled` prop controls whether teleportation happens. When disabled, content renders inline. This pattern handles responsive layouts where modals should overlay on desktop but render inline on mobile:
```vue
```
## Suspense for Async Component Orchestration
Suspense coordinates async dependencies across a component tree. When any descendant component has an unresolved async dependency, Suspense displays the fallback slot content. Once all dependencies resolve, Suspense switches to the default slot.
> **Experimental Status**
>
> Suspense remains experimental in Vue 3.5. The API may change before reaching stable status. Production usage requires accepting this risk.
```vue
```
Suspense tracks two types of async dependencies: components with `async setup()` and async components created with `defineAsyncComponent`.
### Async Setup with Top-Level Await
Vue 3 script setup supports top-level await. Any component using top-level await becomes an async dependency that Suspense can track:
```vue
{{ user.name }}
{{ user.email }}
```
This component cannot render until the fetch completes. A parent Suspense boundary displays the fallback until resolution. Without a Suspense boundary, the component simply does not render.
## Nested Suspense with the suspensible Prop
Complex applications often have multiple async boundaries. Vue 3.3 introduced the `suspensible` prop to control how nested Suspense components interact with their parents.
```vue
```
When `suspensible` is set, the inner Suspense registers with the parent Suspense boundary. The parent waits for both `AsyncNavigation` and `AsyncContent` to resolve before hiding its fallback. The inner Suspense still serves as a local boundary: if `AsyncContent` takes longer, `ContentSkeleton` displays while `AsyncNavigation` remains visible.
Without `suspensible`, the inner Suspense operates independently. The parent shows its fallback only while `AsyncNavigation` loads, ignoring `AsyncContent` entirely.
## Combining Teleport, Suspense, and Transitions
Real applications combine these patterns. A modal that loads content asynchronously benefits from all three:
```vue
```
The nesting order matters: Teleport wraps Transition, which wraps the conditional element, which contains Suspense. This ensures the transition animates the entire modal including loading states.
## Error Handling with Suspense
Suspense does not handle errors. Failed async dependencies reject their promises and propagate errors up the component tree. The `onErrorCaptured` lifecycle hook catches these errors at the boundary:
```vue
Failed to load: {{ error.message }}
```
This pattern wraps any async component tree with both loading and error states. The retry button clears the error, causing Vue to re-render and re-attempt the async operation.
## Interview Questions on Teleport and Suspense
Senior Vue positions increasingly test these patterns. Common questions and what distinguishes strong answers:
**Q: When should Teleport be used over CSS positioning?**
Weak answer: "When z-index does not work."
Strong answer: Teleport solves DOM hierarchy issues that CSS cannot. A modal inside a container with `overflow: hidden` or `transform` creates a new stacking context, breaking `position: fixed`. Teleport moves the modal to `body`, escaping these constraints while preserving Vue's logical component tree.
**Q: How does Suspense differ from loading states in each component?**
Weak answer: "Suspense is cleaner."
Strong answer: Suspense coordinates multiple async dependencies. Ten components with individual loading states flash ten spinners at different times. Suspense shows one spinner until all ten resolve, then reveals them together. This creates smoother perceived performance and simpler component code since async components do not need to manage their own loading states.
**Q: What happens when a Teleport target does not exist?**
The content does not render and Vue logs a warning. Vue 3.5's `defer` prop addresses this by waiting for other components to mount first. Without `defer`, ensure targets exist in `index.html` or in a parent component that mounts before children.
**Q: Can Suspense work with the Options API?**
Yes. Any component with `async setup()` triggers Suspense, regardless of whether it uses Composition API or Options API elsewhere. The setup function is the async boundary, not the component style.
## Teleport and Suspense in Nuxt 3
Nuxt 3 extends these patterns with SSR considerations. The [Nuxt documentation on SSR](https://nuxt.com/docs/guide/concepts/rendering) covers hydration timing.
For Teleport, Nuxt requires the target to exist before hydration. Add portal targets to `app.vue` or use the `defer` prop:
```vue
```
For Suspense, Nuxt's `useFetch` and `useAsyncData` integrate automatically. Page components using these composables work with Nuxt's built-in Suspense without manual configuration. See the [SharpSkill Vue composables module](/technologies/vue-nuxt/interview-questions/vue-composables) for related interview preparation.
## Production Patterns for Vue 3.5
- **Teleport targets in index.html**: Create stable portal targets that exist before any Vue code runs. This avoids timing issues entirely.
- **Granular Suspense boundaries**: One Suspense per independent loading unit. A dashboard with separate widgets benefits from separate Suspense boundaries so fast widgets appear immediately.
- **Error boundaries above Suspense**: Always wrap Suspense with error handling. Network failures and API errors must not crash the entire tree.
- **Transition timing**: When combining Suspense with Transition, set `mode="out-in"` to prevent overlap during state changes.
---
Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack.
HTML version of this page: https://sharpskill.dev/en/blog/vue-nuxt/vue-3-teleport-suspense-advanced-patterns