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

Links the build can check

Link between pages with Link, check route patterns at build time, and control early loading.

Last page, pages/blog/[slug].tsrx became the route /blog/:slug. Now link to it.

A typo in a link often hides until someone clicks it. With the router, a wrong route pattern stops the build.

The router writes a list of your routes at build time. Every pattern link must match an entry in that list. On a click, the browser keeps the page it has. The router asks the server for the next page and swaps in only the page area.

Click a link inside the page.

What happens when you click a link to your own page?

Click a link inside the page, like About or First post. Watch the address bar and the dashed page area.

The pageTry it
Home
my-app.example/
page area

Home

Welcome. Pick a page above.

Your code: Nav.tsrx, used by every page
import { Link } from '@markless/router'; export default function Nav() @{ <nav> <Link href="/">Home</Link> <Link href="/about">About</Link> <Link href="/blog/[slug]" params={{ slug: 'hello' }}>First post</Link> (the build writes /blog/hello) </nav>}
What the router did
Times the whole page loaded1only when you opened it
Page areas asked for0one per click
  1. Nothing yet. Click a link in the page.

Simplified. This needs a multi-page app made with the router. Markless itself does not need a server. A real link starts its request early, when you point at it, focus it, or press it. The click then uses that same request. The router's own tests check this.

Notice that the address bar changes, but the whole page loads only once.

import { Link } from '@markless/router';

export default function Home() @{
	<nav>
		<Link href="/about">About</Link>
		<Link href="/blog/[slug]" params={{ slug: 'hello' }}>First post</Link>
	</nav>
}

Link renders a real <a href>. For the second link, the build writes href="/blog/hello" and drops params. A plain <a> with a pattern and params works the same way.

What the build checks

You wrote Result
href="/blog/[slug]" with params={{ slug }} builds, and href becomes the real URL
href="/blog/[id]" (no such route) Typed route error: /blog/[id] does not match any route in pages/.
href="/blog/[slug]" with no params Typed route error: /blog/[slug] requires params:
href="/abuot" the build passes, and a type check flags it

The router writes route types to .output/markless/router/types/routes.d.ts. The file markless-router-env.d.ts in your app root points TypeScript at them.

Loading before the click

A link to one of your pages starts to load that page early. A pointer over it, a focus, or a press starts the load. When the page is idle, a few visible links load too. Links to api/ endpoints never load early.

Prop Effect
prefetch={false} nothing loads before the click
replace replaces the history entry instead of adding one
scroll={false} keeps the scroll position

Back and Forward bring back each page and its scroll position. Plain <a> links to your pages navigate the same way. If the fetch fails, the browser loads the URL normally.

Next: How does a page wait for slow data? Data loading →

Was this page helpful?