Litro ships a built-in client-side router (LitroRouter) built on the native URLPattern API. No external router dependency.
Use <litro-link> for SPA navigation. Plain <a> tags cause full page reloads:
<!-- SPA navigation — no full reload -->
<litro-link href="/docs/getting-started">Getting Started</litro-link>
<!-- Full page reload (browser default) -->
<a href="/docs/getting-started">Getting Started</a>
import { LitroRouter } from '@beatzball/litro-router';
LitroRouter.go('/docs/getting-started');
The router passes parsed parameters to onBeforeEnter:
@customElement('page-blog-slug')
export class BlogSlugPage extends LitroPage {
_slug = '';
override onBeforeEnter(location: LitroLocation) {
this._slug = location.params.slug ?? '';
}
override render() {
return html`<p>Slug: ${this._slug}</p>`;
}
}
The router handles popstate events from fragment links (#hash). It automatically scrolls to the target heading after mount, traversing shadow DOM roots to find the element.
The crawlLinks option does not find LitroRouter routes automatically. Add all static page routes to prerender.routes explicitly. Litro's SSG plugin handles this via generateRoutes() exports on page files.