--- title: Streaming with Suspense --- # Streaming with Suspense [MODES: framework, data]

Streaming with React Suspense allows apps to speed up initial renders by deferring non-critical data and unblocking UI rendering. React Router supports React Suspense by returning promises from loaders and actions. ## 1. Return a promise from loader React Router awaits route loaders before rendering route components. To unblock the loader for non-critical data, return the promise instead of awaiting it in the loader. ```tsx import type { Route } from "./+types/my-route"; export async function loader({}: Route.LoaderArgs) { // note this is NOT awaited let nonCriticalData = new Promise((res) => setTimeout(() => res("non-critical"), 5000), ); let criticalData = await new Promise((res) => setTimeout(() => res("critical"), 300), ); return { nonCriticalData, criticalData }; } ``` Note you can't return a single promise, it must be an object with keys. ## 2. Render the fallback and resolved UI The promise will be available on `loaderData`, `` will await the promise and trigger `` to render the fallback UI. ```tsx import * as React from "react"; import { Await } from "react-router"; // [previous code] export default function MyComponent({ loaderData, }: Route.ComponentProps) { let { criticalData, nonCriticalData } = loaderData; return (

Streaming example

Critical data value: {criticalData}

Loading...
}> {(value) =>

Non critical value: {value}

}
); } ``` ## With React 19 If you're experimenting with React 19, you can use `React.use` instead of `Await`, but you'll need to create a new component and pass the promise down to trigger the suspense fallback. ```tsx Loading...}> ``` ```tsx function NonCriticalUI({ p }: { p: Promise }) { let value = React.use(p); return

Non critical value {value}

; } ``` ## Timeouts By default, loaders and actions reject any outstanding promises after 4950ms. You can control this by exporting a `streamTimeout` numerical value from your `entry.server.tsx`. ```ts filename=entry.server.tsx // Reject all pending promises from handler functions after 10 seconds export const streamTimeout = 10_000; ```