Skip to main content
Vertz routing is fully typed — route patterns, parameters, and navigation are all checked at compile time. If you add a route for /tasks/:id, then navigate({ to: '/tasks/:id', params: { id: 'abc' } }) compiles but navigate({ to: '/bogus' }) doesn’t.

Define routes

Use defineRoutes() to declare your route map:
Each key is a URL pattern. Each value is a route config with at least a component factory.

Dynamic segments

Use :param in the path for dynamic segments:

Create the router

Pass your routes to createRouter():
The router listens to popstate events and matches the current URL against your routes.

Render with RouterView

RouterView renders the matched route’s component and handles transitions:
RouterView handles:
  • Sync and async (lazy-loaded) components
  • Stale resolution guards — if a slow route resolves after a newer navigation, it’s discarded
  • Automatic cleanup of the previous page

useRouter()

Pages access navigation via context — no prop threading:

Typed navigation

Scaffolded apps get typed useRouter() automatically after codegen runs:
Now navigate() is constrained to valid route patterns and params:
The generated typing lives in .vertz/generated/router.d.ts. If you build a project by hand, make sure .vertz/generated is included in tsconfig.json.

Replace vs push

Use { replace: true } to replace the current history entry instead of pushing:

Access route params

Use useParams() to access typed route parameters:
The type parameter tells TypeScript which path pattern to extract params from:
  • useParams<'/tasks/:id'>() returns { id: string }
  • useParams<'/users/:userId/posts/:postId'>() returns { userId: string; postId: string }

Param validation with schemas

Routes can validate and parse params at the routing layer using a params schema:
When a route has a params schema:
  • Valid params are parsed and available via useParams() with the parsed types
  • Invalid params (e.g., /tasks/not-a-uuid) don’t match the route — the fallback renders instead
You can also parse params into non-string types:

Nested routes

Use children for layout routes with nested pages:
The layout component uses Outlet to render the matched child:

Pre-rendering (SSG)

Routes can be pre-rendered to static HTML at build time. Add prerender: true for static routes, or generateParams for dynamic routes:
When you run vertz build, routes with prerender: true or generateParams are rendered to dist/client/<path>/index.html. See the SSG guide for details.

Lazy-loaded routes

Return a dynamic import from component for code splitting:
The router resolves the promise and renders the default export.