Switch from route-recognizer to matchit#4096
Conversation
Migrate `yew-router` from the unmaintained `route-recognizer` crate to
`matchit` 0.9, aligning route parameter syntax with Axum and the broader
Rust ecosystem (`:param` → `{param}`, `*wildcard` → `{*wildcard}`).
|
Visit the preview URL for this PR (updated for commit 5927cc5): https://yew-rs--pr4096-feat-matchit-migrati-wpdp8olt.web.app (expires Wed, 08 Apr 2026 05:05:56 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Size ComparisonDetails
✅ None of the examples has changed their size significantly. |
Benchmark - SSRYew MasterDetails
Pull RequestDetails
|
matchit has stricter conflict detection than route-recognizer, so
users migrating with ambiguous routes (e.g. `/{id}` and `/{name}`)
will hit this panic. The old message ("failed to insert route") gave
no indication of which route or why; now it shows both.
A unit variant like `Settings` with `#[at("/settings/{*_rest}")]`
compiled but produced a broken `to_path()` that returned the literal
pattern string. This was a pre-existing bug (same with the old
`*rest` syntax) now caught at compile time.
Also fixes the nested-router docs examples to use named fields.
Under matchit, the old route-recognizer syntax silently becomes literal path segments, causing routes to never match. Emit a compile-time error with a suggested fix instead.
|
One thing worth adding: a compile-time guard against the old Without it, a user who upgrades yew-router and forgets to rewrite axum ran into the same problem when they upgraded matchit in 0.8 (tokio-rs/axum#2645). Their solution was a runtime panic in Since yew-router has route patterns in |
* feat(yew-router)!: switch from route-recognizer to matchit
Migrate `yew-router` from the unmaintained `route-recognizer` crate to
`matchit`, aligning route parameter syntax with Axum and the broader
Rust ecosystem (`:param` → `{param}`, `*wildcard` → `{*wildcard}`).
* fix(yew-router): include route pattern and error in build_router panic
matchit has stricter conflict detection than route-recognizer, so
users migrating with ambiguous routes (e.g. `/{id}` and `/{name}`)
will hit this panic. The old message ("failed to insert route") gave
no indication of which route or why; now it shows both.
* fix(yew-router-macro): reject route params without corresponding fields
A unit variant like `Settings` with `#[at("/settings/{*_rest}")]`
compiled but produced a broken `to_path()` that returned the literal
pattern string. This was a pre-existing bug (same with the old
`*rest` syntax) now caught at compile time.
Also fixes the nested-router docs examples to use named fields.
* fix(yew-router-macro): reject old `:param` and `*param` route syntax
Under matchit, the old route-recognizer syntax silently becomes literal
path segments, causing routes to never match. Emit a compile-time error
with a suggested fix instead.
The motivation is well-explained in #4057
Also added a unit test for nested router behavior as documented on yew.rs
This is a breaking change and we will need a migration guide at yew-router release.
Apart from the obvious syntax change, note that ambiguous route parameters now panic instead of silently shadowing
Example that previously "worked" but now panics:
Previously
route-recognizersilently accepted both and arbitrarily matched the last one registered, soByIdwas unreachable. Nowmatchitrejects the conflict at router initialization with:Fix: disambiguate the routes with a static prefix:
This only affects routes that were already broken (one variant silently unreachable). If somebody's app worked correctly before, this change won't affect them.
Checklist