Minor Changes
-
BREAKING CHANGE: Remove the
compareFnparameter frommatchandmatchAllmethodsMatches always sort by specificity (most specific first). If you need a different order, sort the result of
matchAllyourself.import * as Specificity from 'remix/route-pattern/specificity' // before matcher.matchAll(url, Specificity.ascending) // after matcher.matchAll(url).sort(Specificity.ascending)
-
BREAKING CHANGE: New modular APIs and subpath exports
Previously, this package shipped the default export and a
/specificityexport.
A typical Remix app does not do any client-side matching but all the matching logic would ship to the browser anyway causing JS bloat.Now, features are organized into separate subpath exports, so even without a bundler, only the code you need ends up in the browser.
For example, this reduced JS fromroute-patternindemos/bookstorefrom 25kB (14.9kB compressed) to 8.8kb (7kB compressed) which amounts to ~65% reduction (~53% reduction compressed).To achieve this, we've reworked our core APIs to be simpler and more independently useful.
So instead of a singleRoutePatternclass that does it all (.href,.match, ...), the newRoutePatternclass is a thin layer around the parsed pattern that includesRoutePattern.parsestatic method for parsing and.source,.toString()and.toJSON()for serialization.The rest of the functionality comes from dedicated subpath exports:
- remix/route-pattern/href : Generate hrefs for patterns with type safe params.
- remix/route-pattern/match : Match against one pattern with type inference for params. Or match against many patterns with deterministic ranking and attached data.
- remix/route-pattern/join : Combine two patterns into one. Override protocol, hostname, port. Join pathnames. Merge search constraints.
remix/route-pattern/specificity remains the same as before, providing utilities for ranking matches.
Additionally,
ArrayMatcherandTrieMatcherhave been replaced bycreateMultiMatcher(which is now always backed by trie-based matching).
To match against only a single pattern while receiving type safeparamsfrom the match, usecreateMatcher.See the new README for details.
Patch Changes
-
Encode href params so pathname params cannot inject URL path, dot segment, query, or hash syntax. Wildcard pathname params now preserve slash-separated structure while encoding each segment, and hostname params are normalized or rejected when they would inject URL authority, path, query, or hash syntax. Matchers now decode generated pathname params so reserved characters like
/,?, and#round-trip as param content. -
Do not allow partial matches for variables and wildcards in pathname
let matcher = createMultiMatcher<string>() matcher.add('/files/:name.md', 'original') matcher.add('/files/:name.md.backup', 'backup') // before: 'original' included since `:name.md` partially matches `readme.md.backup` matcher.matchAll('https://example.com/files/readme.md.backup').map((match) => match.data) // ❌ ['backup', 'original'] // after: only matches when the pattern covers the whole segment matcher.matchAll('https://example.com/files/readme.md.backup').map((match) => match.data) // ✅ ['backup']
-
Fix matcher to match origin-less patterns (e.g.
/,/about) against URLs that have an explicit port. Previously a pattern like/would not matchhttp://localhost:44199/.