diff --git a/.changeset/eleven-oranges-design.md b/.changeset/eleven-oranges-design.md new file mode 100644 index 0000000000..a5ca0a4068 --- /dev/null +++ b/.changeset/eleven-oranges-design.md @@ -0,0 +1,5 @@ +--- +"react-router": patch +--- + +Properly escape interpolated :param values in generatePath() diff --git a/packages/react-router/__tests__/generatePath-test.tsx b/packages/react-router/__tests__/generatePath-test.tsx index 70232f7d46..d15899d347 100644 --- a/packages/react-router/__tests__/generatePath-test.tsx +++ b/packages/react-router/__tests__/generatePath-test.tsx @@ -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"); }); @@ -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(); diff --git a/packages/react-router/lib/router/utils.ts b/packages/react-router/lib/router/utils.ts index cebea7406f..0d494edb0f 100644 --- a/packages/react-router/lib/router/utils.ts +++ b/packages/react-router/lib/router/utils.ts @@ -1108,7 +1108,7 @@ export function generatePath( const [, key, optional] = keyMatch; let param = params[key as PathParam]; invariant(optional === "?" || param != null, `Missing ":${key}" param`); - return stringify(param); + return encodeURIComponent(stringify(param)); } // Remove any optional markers from optional static segments