Skip to content

Async & Suspense

Async Components

defineAsyncComponent creates a component that loads lazily via a promise-based loader:

ts
import { defineAsyncComponent, h } from 'nexa-framework'

const AsyncComp = defineAsyncComponent({
  loader: () => import('./MyComponent.nexa'),
})

Options

OptionTypeDescription
loader() => Promise<Component>Function that returns a promise resolving to a component
loadingComponentComponentComponent to render while loading
errorComponentComponentComponent to render on error
delaynumber (ms)Delay before showing the loading component
timeoutnumber (ms)Timeout after which to show the error component

Usage

ts
const AsyncComp = defineAsyncComponent({
  loader: () => import('./MyComponent.nexa'),
  loadingComponent: Spinner,
  errorComponent: ErrorDisplay,
  delay: 200,
  timeout: 5000,
})

Suspense

Suspense coordinates multiple async components, showing fallback content until all resolve:

ts
import { Suspense, defineAsyncComponent, h } from 'nexa-framework'

const App = defineComponent({
  render() {
    return h(Suspense, {
      fallback: () => h('div', null, ['Loading...']),
    }, [
      h(Header, null),
      h(MainContent, null),
    ])
  },
})

While any child async component is still loading, Suspense renders the fallback. Once all resolve, Suspense swaps to the actual content and hides the fallback.

Key Behavior

  • Async components mount in a hidden container during the loading phase to trigger resolution
  • When all async dependencies resolve, content becomes visible and fallback is hidden
  • Component state is preserved across the ready transition

Error Boundaries

ErrorBoundary catches rendering errors in child components and displays fallback UI:

ts
import { defineComponent, h, ErrorBoundary } from 'nexa-framework'

const SafeSection = defineComponent({
  render() {
    return h(ErrorBoundary, {
      fallback: (err) => h('div', { class: 'error' }, [err.message]),
    }, [
      h(UnstableComponent, null),
    ])
  },
})

Without Fallback

If no fallback prop is provided, a default error message is shown:

ts
h(ErrorBoundary, null, [h(RiskyComponent, null)])

Error Propagation

Errors are caught at the ErrorBoundary boundary level. Nested boundaries catch errors from their respective subtrees independently.

Released under the MIT License.