Skip to content

Fix #558: Make ~ paths respect Router base prop - #577

Draft
molefrog wants to merge 1 commit into
mainfrom
cursor/fix-tilde-base-558-db59
Draft

molefrog wants to merge 1 commit into
mainfrom
cursor/fix-tilde-base-558-db59

Conversation

@molefrog

@molefrog molefrog commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Problem

When a Router has a base prop and you use ~ prefix for absolute-within-app paths, the navigation ignores the Router base and navigates outside the expected scope.

For example, with <Router base="/app">, a link <Link href="~/schedule"> would navigate to /schedule instead of the expected /app/schedule.

The ~ prefix is documented as an escape hatch to navigate to absolute paths when using nested routes, but the implementation was treating it as "absolute on the domain" rather than "absolute within the app".

Solution

This fix makes ~ paths respect the outermost explicit Router base prop while still escaping from nested route bases (created by <Route nest>).

The implementation:

  • Adds an explicitBase property to the router context that tracks only the outermost explicit Router base
  • Nested routes created with <Route nest> inherit explicitBase without modifying it
  • When resolving ~ paths, the router uses explicitBase instead of ignoring all bases

Behavior

Before: With <Router base="/app">, ~/schedule navigates to /schedule
After: With <Router base="/app">, ~/schedule navigates to /app/schedule

This matches the expected semantics where ~ means "absolute within the app" rather than "absolute on the domain".

Testing

  • Added test reproducing the exact scenario from issue Links using ~ do not respect base聽#558
  • Updated existing tests to reflect the new behavior
  • All tests pass (271 pass, 1 skip, 0 fail)
  • Type checks pass
  • Lint checks pass
  • Bundle size unchanged (still within limits)

Fixes #558

Open in Web聽Open in Cursor聽

The ~ prefix is meant to escape from nested route bases and navigate
to absolute paths within the app. Before this fix, ~/path would ignore
all bases including the explicit Router base prop, navigating to /path
on the domain root.

After this fix, ~/path respects the outermost explicit Router base.
With <Router base="/app">, ~/schedule navigates to /app/schedule
instead of /schedule, matching the expected behavior where ~ means
"absolute within the app" rather than "absolute on the domain".

Implementation:
- Add explicitBase property to router context that tracks only the
  outermost explicit Router base prop (not nested route bases)
- Mark Routers created by nested Routes with internal _nested flag
- Update absolutePath() and Link href generation to use explicitBase
  for ~ paths instead of ignoring the base entirely

Tests updated to reflect new behavior and verify the fix for the
reported issue scenario.

Co-authored-by: Alexey Taktarov <molefrog@users.noreply.github.com>
@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown

size-limit report 馃摝

Path Size
packages/wouter/src/index.js 2.35 KB (+2.35% 馃敽)
packages/wouter/src/use-browser-location.js 555 B (0%)
packages/wouter/src/memory-location.js 729 B (0%)
packages/wouter/src/url-pattern.js 223 B (0%)
packages/wouter/src/use-hash-location.js 720 B (0%)
packages/wouter-preact/src/index.js 2.24 KB (+2.82% 馃敽)
packages/wouter-preact/src/use-browser-location.js 488 B (0%)
packages/wouter-preact/src/use-hash-location.js 645 B (0%)
packages/wouter-preact/src/memory-location.js 664 B (0%)
packages/wouter-preact/src/url-pattern.js 223 B (0%)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Links using ~ do not respect base

2 participants