-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Regression of #13595 - URLs with optional segments should still be included non-expanded in typed href helper if they are unambiguous (no static optional segments) by the supplied params object #13694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What would be perfect would be a merge between 7.6.0 and 7.6.1 behavior:
would turn into (add these two) (already exist in current version) |
I don't really have the time to submit a PR and get known with the contributing process, but here's a TS Play with a method that could replace the exploding method. function explodeOptionalSegments(path: string): string[] {
let segments = path.split("/");
if (segments.length === 0) return [];
let [first, ...rest] = segments;
// Optional path segments are denoted by a trailing `?`
let isOptional = first.endsWith("?");
// Compute the corresponding required segment: `foo?` -> `foo`
let required = first.replace(/\?$/, "");
// Check if this is a dynamic parameter (starts with :)
let isDynamic = required.startsWith(":");
if (rest.length === 0) {
// Interpret empty string as omitting an optional segment
// `["one", "", "three"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`
// If it's an optional dynamic param, also include the version with ?
if (isOptional) {
let results = [required, ""];
if (isDynamic) {
results.push(first); // Include the version with ? for dynamic params
}
return results;
}
return [required];
}
let restExploded = explodeOptionalSegments(rest.join("/"));
let result: string[] = [];
// All child paths with the prefix. Do this for all children before the
// optional version for all children, so we get consistent ordering where the
// parent optional aspect is preferred as required. Otherwise, we can get
// child sections interspersed where deeper optional segments are higher than
// parent optional segments, where for example, /:two would explode *earlier*
// then /:one. By always including the parent as required *for all children*
// first, we avoid this issue
result.push(
...restExploded.map((subpath) =>
subpath === "" ? required : [required, subpath].join("/")
)
);
// Then, if this is an optional value, add all child versions without
if (isOptional) {
result.push(...restExploded);
// If this is an optional dynamic param, also add versions where it stays optional
if (isDynamic) {
result.push(
...restExploded.map((subpath) =>
subpath === "" ? first : [first, subpath].join("/")
)
);
}
}
// for absolute paths, ensure `/` instead of empty segment
return result.map((exploded) =>
path.startsWith("/") && exploded === "" ? "/" : exploded
);
}
console.log(explodeOptionalSegments('/:localeOrLocation?/:location?/static?'))
console.log(explodeOptionalSegments('/test?/blabla?/static?'))
console.log(explodeOptionalSegments('/:reallyDynamic?/:dynamic?/static?')) Feel free to use this for fixing this. This is more or less a stylistic choice, but the code above would create the following combos:
It might make sense to only create the fully optional version in case we have multiple dynamic segments. But I'll let that over to you. |
you could also only expand static optional segments (would be the most clean implementation) but that would break anyone on version 7.6.1 that now starts to use the typegen route (only on a typelevel, runtime is unaffected) |
@tobimori thanks for all the investigation you did here! I agree that a key part of what makes |
Fixed by #13725 which will be available next release |
🤖 Hello there, We just published version Thanks! |
Uh oh!
There was an error while loading. Please reload this page.
I'm using React Router as a...
framework
Reproduction
See Expected Behavior for Details
System Info
Used Package Manager
pnpm
Expected Behavior
I'm posting this as a bug report since this working behavior was removed/regressed in a minor release, which breaks a few of our sites.
For example, in a lot of our projects we have multiple optional segments that are dynamic. We then use the href helper everywhere to generate correct URLs, and we always supply the params object from ComponentProps.
For example:
In this case, the inclusion of the params in the object is optional - it perfectly suited the case.
Now, with the new syntax, I'd have to implement the type checking by myself, the helper is now basically useless:
(This would grow large in case you have more optional params, we have like 5 in the largest URL, so this would be quite cumbersome to work around.)
Actual Behavior
There's a type error shown for all links since the working behavior was removed in RR 7.6.1.
Ref: #13595
The text was updated successfully, but these errors were encountered: