--- outline: deep --- # Suspense {#suspense} :::warning Experimental Feature `` is an experimental feature. It is not guaranteed to reach stable status and the API may change before it does. ::: `` is a built-in component for orchestrating async dependencies in a component tree. It can render a loading state while waiting for multiple nested async dependencies down the component tree to be resolved. ## Async Dependencies {#async-dependencies} To explain the problem `` is trying to solve and how it interacts with these async dependencies, let's imagine a component hierarchy like the following: ``` └─ ├─ │ └─ (component with async setup()) └─ ├─ (async component) └─ (async component) ``` In the component tree there are multiple nested components whose rendering depends on some async resource to be resolved first. Without ``, each of them will need to handle its own loading / error and loaded states. In the worst case scenario, we may see three loading spinners on the page, with content displayed at different times. The `` component gives us the ability to display top-level loading / error states while we wait on these nested async dependencies to be resolved. There are two types of async dependencies that `` can wait on: 1. Components with an async `setup()` hook. This includes components using ` ``` ### Async Components {#async-components} Async components are **"suspensible"** by default. This means that if it has a `` in the parent chain, it will be treated as an async dependency of that ``. In this case, the loading state will be controlled by the ``, and the component's own loading, error, delay and timeout options will be ignored. The async component can opt-out of `Suspense` control and let the component always control its own loading state by specifying `suspensible: false` in its options. ## Loading State {#loading-state} The `` component has two slots: `#default` and `#fallback`. Both slots only allow for **one** immediate child node. The node in the default slot is shown if possible. If not, the node in the fallback slot will be shown instead. ```vue-html ``` On initial render, `` will render its default slot content in memory. If any async dependencies are encountered during the process, it will enter a **pending** state. During the pending state, the fallback content will be displayed. When all encountered async dependencies have been resolved, `` enters a **resolved** state and the resolved default slot content is displayed. If no async dependencies were encountered during the initial render, `` will directly go into a resolved state. Once in a resolved state, `` will only revert to a pending state if the root node of the `#default` slot is replaced. New async dependencies nested deeper in the tree will **not** cause the `` to revert to a pending state. When a revert happens, fallback content will not be immediately displayed. Instead, `` will display the previous `#default` content while waiting for the new content and its async dependencies to be resolved. This behavior can be configured with the `timeout` prop: `` will switch to fallback content if it takes longer than `timeout` to render the new default content. A `timeout` value of `0` will cause the fallback content to be displayed immediately when default content is replaced. ## Events {#events} The `` component emits 3 events: `pending`, `resolve` and `fallback`. The `pending` event occurs when entering a pending state. The `resolve` event is emitted when new content has finished resolving in the `default` slot. The `fallback` event is fired when the contents of the `fallback` slot are shown. The events could be used, for example, to show a loading indicator in front of the old DOM while new components are loading. ## Error Handling {#error-handling} `` currently does not provide error handling via the component itself - however, you can use the [`errorCaptured`](/api/options-lifecycle#errorcaptured) option or the [`onErrorCaptured()`](/api/composition-api-lifecycle#onerrorcaptured) hook to capture and handle async errors in the parent component of ``. ## Combining with Other Components {#combining-with-other-components} It is common to want to use `` in combination with the [``](./transition) and [``](./keep-alive) components. The nesting order of these components is important to get them all working correctly. In addition, these components are often used in conjunction with the `` component from [Vue Router](https://router.vuejs.org/). The following example shows how to nest these components so that they all behave as expected. For simpler combinations you can remove the components that you don't need: ```vue-html ``` Vue Router has built-in support for [lazily loading components](https://router.vuejs.org/guide/advanced/lazy-loading.html) using dynamic imports. These are distinct from async components and currently they will not trigger ``. However, they can still have async components as descendants and those can trigger `` in the usual way. ## Nested Suspense {#nested-suspense} When we have multiple async components (common for nested or layout-based routes) like this: ```vue-html ``` `` creates a boundary that will resolve all the async components down the tree, as expected. However, when we change `DynamicAsyncOuter`, `` awaits it correctly, but when we change `DynamicAsyncInner`, the nested `DynamicAsyncInner` renders an empty node until it has been resolved (instead of the previous one or fallback slot). In order to solve that, we could have a nested suspense to handle the patch for the nested component, like: ```vue-html ``` If you don't set the `suspensible` prop, the inner `` will be treated like a sync component by the parent ``. That means that it has its own fallback slot and if both `Dynamic` components change at the same time, there might be empty nodes and multiple patching cycles while the child `` is loading its own dependency tree, which might not be desirable. When it's set, all the async dependency handling is given to the parent `` (including the events emitted) and the inner `` serves solely as another boundary for the dependency resolution and patching. --- **Related** - [`` API reference](/api/built-in-components#suspense)