wouter
wouter copied to clipboard
Support `/base/*?` semantics
TL;DR: the docs are wrong here:
{/* will match everything else */}
<Route path="/:rest*">
{(params) => `404, Sorry the page ${params.rest} does not exist!`}
</Route>
"/:rest*" does not in fact match "everything else" (does not match paths containing empty path segments).
Real world use-case that currently cannot currently be matched in this way: https://en.wikipedia.org/wiki///
Rather than showing the 404 page, the page will be blank for any path containing double slashes!
See https://github.com/WICG/urlpattern/issues/163 for why the existing capability /base/:remaining_path* doesn't cover all the bases! Instead, a pattern that does match everything after /base is /base/*?. For compatibility with react-router's behavior, the * segment's value could be auto-named simply * (cannot conflict with a named identifier since named identifiers must be alphanumeric). The * identifier can be of course renamed in the render function if you don't want to do params['*'], e.g.:
<Route path='/*?'>
{({'*': rest}) => `404, Sorry the page ${rest} does not exist!`}
</Route>
Use-case: with a couple additional customizations, this enhancement will allow a robust nested router architecture.
Alternative: forget about URLPattern's questionable syntax choices and implement the same semantics with /base/*, dropping the trailing ? and staying consistent with react-router:
<Route path='/*'>
{({'*': rest}) => `404, Sorry the page ${rest} does not exist!`}
</Route>
2nd Alternative: update the current behavior to align with the docs (even though this isn't currently compatible with URLPattern or path-to-regexp), and allow the existing syntax of /:remaining_path* to match arbitrary paths (including those with empty path segments in them). We could then do /base/:_* to achieve the same thing as react-router's /base/*. Not quite as concise (which could be annoying for users who are repeating this pattern constantly), but it would work.