Skip to content
These are temporary community docs. The official docs are in progress.Help improve them
Markless
Esc
↑↓navigate↵open⌘Jpreview
On this page

Data that arrives in the same response

Load page data with an async computed value inside @try, and the server sends it in the same response.

Last page, a click asked the server for the next page. So what happens when that page waits for slow data?

There is no special loader function. A page loads data the way any component does: an async computed() inside @try.

Think of a restaurant that brings your bread first. The main dish comes later, to the same table. This is an analogy.

Press Next to step through one page load.

What does the page show while its data loads?

Drag the timeline or press Next. Then switch to Quick data and compare.

How fast the greeting loads
1. The browser asks for /feed

One request goes out. The page file runs and starts to load the greeting.

The pageTry it
Loading
my-app.example/feed

The browser is waiting for the first part.

Your code: pages/feed.tsrx
export default function Feed({ url }: PageProps) @{ (runs for /feed) const data = computed(async () => slowGreeting(url.pathname)); (starts loading) <main> <h1>Feed</h1> @try { <p>{data.text}</p> } @pending { <p>Loading...</p> } @catch { <p>Failed</p> } </main>}
What the browser got
Requests the browser made1for the whole page
Parts of the response so far0
  1. noteThe browser asked for /feed. This is the only request.

Simplified. This is a multi-page app made with the router, so a server makes each page. Markless itself does not need a server. We ran this page in an app made from the full-stack starter. With slow data, the heading and Loading... came first, and the greeting came later in the same response. With quick data, the greeting came in the first part.

Notice that the data comes in the same response. The browser makes no second request.

The code

import { computed } from '@markless/core';
import type { PageProps } from '@markless/router';
import { slowGreeting } from '../lib/slow.ts';

export default function Feed({ url }: PageProps) @{
	const data = computed(async () => slowGreeting(url.pathname));

	<main>
		<h1>Feed</h1>
		@try {
			<p>{data.text}</p>
		} @pending {
			<p>Loading...</p>
		} @catch {
			<p>Failed</p>
		}
	</main>
}

If slowGreeting is slow, one response comes in two parts:

  1. The heading and the @pending content come first.
  2. When the data is ready, the same response adds the @try content. The page puts it in place, and the response ends.

If the data is ready quickly, the server puts it in the first part. You turn nothing on.

For the rules of async values, see Async.

Coming from another framework?

The router has no loader or action export. A page gets only params, url, and status as props. Data comes from async values in the page, and slow parts stream in the same response.

Next: What if the data comes from your own server? API routes →

Was this page helpful?