Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eleven-oranges-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-router": patch
---

Properly escape interpolated :param values in generatePath()
10 changes: 8 additions & 2 deletions packages/react-router/__tests__/generatePath-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,8 @@ describe("generatePath", () => {
).toBe("/courses/foo*");
});
it("handles a 0 parameter", () => {
// @ts-expect-error
// incorrect usage but worked in 6.3.0 so keep it to avoid the regression
expect(generatePath("/courses/:id", { id: 0 })).toBe("/courses/0");
// @ts-expect-error
// incorrect usage but worked in 6.3.0 so keep it to avoid the regression
expect(generatePath("/courses/*", { "*": 0 })).toBe("/courses/0");
});
Expand Down Expand Up @@ -135,6 +133,14 @@ describe("generatePath", () => {
});
});

describe("with a param that contains a /", () => {
it("properly encodes the slash", () => {
expect(generatePath("/courses/:id/grades", { id: "a/b" })).toBe(
"/courses/a%2Fb/grades"
);
});
});

it("throws only on on missing named parameters, but not missing splat params", () => {
expect(() => generatePath(":foo")).toThrow();
expect(() => generatePath("/:foo")).toThrow();
Expand Down
2 changes: 1 addition & 1 deletion packages/react-router/lib/router/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ export function generatePath<Path extends string>(
const [, key, optional] = keyMatch;
let param = params[key as PathParam<Path>];
invariant(optional === "?" || param != null, `Missing ":${key}" param`);
return stringify(param);
return encodeURIComponent(stringify(param));
}

// Remove any optional markers from optional static segments
Expand Down