Skip to content

[alpha.5] #1 — Client Router Core #115

Description

@SisyphusZheng

Parent

#114 — v0.41.0-alpha.5: SPA Mode + Deno Desktop Proof

What to build

Add a real client-side URL router to @openelement/router. Currently this package only has a data-context stack for loader/action hooks — no actual URL routing. This slice delivers the core routing engine: URL pattern matching, history-based and hash-based navigation, route params extraction, and async route guards.

Dual-mode navigation:

  • 'history' mode (default) — uses pushState/popstate for clean URLs like /products/42
  • 'hash' mode — uses #/products/42 for file:// and embedded contexts
  • 'auto' mode — detects file:// protocol and switches to hash automatically

Route matching:

  • Params extraction: /products/:id{ id: '42' }
  • Query string parsing: ?sort=asc&page=2
  • Optional async guard functions that can block or redirect navigation

Integration with file-system routes:

  • At build time, the Vite plugin generates a route manifest from routes/*.tsx files
  • Runtime consumes the manifest to match URLs to components
  • Manual defineRoute() also supported as escape hatch

Acceptance criteria

  • createRouter({ mode: 'history' }) returns a router that listens to pushState/popstate
  • createRouter({ mode: 'hash' }) returns a router that uses #/ segments
  • createRouter({ mode: 'auto' }) picks hash when location.protocol === 'file:'
  • Route matching extracts named params from /products/:id/:slug?
  • Query string is parsed and available in route context
  • Async guard can block navigation (return false) or redirect (return path string)
  • Router exposes navigate(path) and replace(path) methods
  • router.dispose() removes all event listeners
  • Tests cover: history nav, hash nav, auto mode, params extraction, guard blocking, guard redirect, dispose cleanup

Blocked by

None — can start immediately

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions