Components

<Loading>

Edit this page

Loading is a component that shows fallback UI while its subtree has unresolved async values. It is non-blocking — both the fallback and children exist at the same time, even if not currently in the DOM.

import { Loading } from "solid-js"
import type { JSX } from "solid-js"
function Loading(props: {
fallback?: JSX.Element
children: JSX.Element
}): JSX.Element

Basic usage

<Loading fallback={<LoadingSpinner />}>
<AsyncComponent />
</Loading>

Loading is intended for initial readiness: it handles the first time a subtree reads async values that aren't ready yet. After the subtree has produced a value, subsequent revalidation should generally not show the fallback again — use isPending for that.


Nested boundaries

Loading boundaries can be nested to control where loading UI appears. Only the nearest ancestor boundary shows its fallback when an async value is pending:

const title = createMemo(() => fetchTitle())
const data = createMemo(() => fetchData())
<Loading fallback={<div>Loading page...</div>}>
<h1>{title()}</h1>
<Loading fallback={<div>Loading data...</div>}>
<DataComponent data={data()} />
</Loading>
</Loading>

How it works

When a computation (like createMemo) returns a Promise, reading the accessor before the Promise resolves causes suspension. Loading catches this suspension and displays the fallback. Once the Promise resolves, the content renders automatically.

const user = createMemo(() => fetchUser(userId()))
<Loading fallback={<Spinner />}>
<div>{user().name}</div>
</Loading>

Migration

// 1.x
import { Suspense } from "solid-js"
<Suspense fallback={<Spinner />}>
<AsyncComponent />
</Suspense>
// 2.0
import { Loading } from "solid-js"
<Loading fallback={<Spinner />}>
<AsyncComponent />
</Loading>

Props

NameTypeDescription
fallbackJSX.ElementThe fallback component to render while async values are pending.
Report an issue with this page