Skip to content
renkudocs

Watch this page stream.

A waits 5 seconds; B waits 2. Both waits are deliberate. B finishes first.

Result A

Waiting for the server

The shell is already here. This region is still waiting.

Result B

Waiting for the server

The shell is already here. This region is still waiting.

Replay streaming demo ↻One document request. Two independent results.

Still waiting? Check that JavaScript is enabled, then replay the demo.

The boundary is the unit of waiting.

The Worker sends the document and both loading states first. Each result travels in a later patch; the browser waits for the patch's completion marker before replacing its fallback. The source below recreates this behavior.

src/streaming.tsrx
import { Boundary } from "renku";

async function Result({ seconds }: { seconds: number }) {
  // A deliberate wait for this demo. Your data work goes here.
  await new Promise(resolve => setTimeout(resolve, seconds * 1000));
  return @{ <p>Ready after {seconds} seconds.</p> };
}

export default function Streaming() @{
  <section>
    <Boundary fallback={<p>Waiting for 5 seconds…</p>}
              error={<p>This result could not load.</p>}>
      <Result seconds={5} />
    </Boundary>
    <Boundary fallback={<p>Waiting for 2 seconds…</p>}
              error={<p>This result could not load.</p>}>
      <Result seconds={2} />
    </Boundary>
  </section>
}

Styling omitted. This demo uses cancellable server timers; pass context.signal to your own async work.

Without JavaScript, the shell and fallbacks remain readable. Keep essential content in the shell. Read the streaming guide →