diff --git a/contributors.yml b/contributors.yml index 0b37da1725..f86ca20b2c 100644 --- a/contributors.yml +++ b/contributors.yml @@ -309,3 +309,4 @@ - yuleicul - zeromask1337 - zheng-chuang +- dunnai diff --git a/packages/react-router/__tests__/dom/navigate-encode-params-test.tsx b/packages/react-router/__tests__/dom/navigate-encode-params-test.tsx index c20d1a2f8c..99ab9ea425 100644 --- a/packages/react-router/__tests__/dom/navigate-encode-params-test.tsx +++ b/packages/react-router/__tests__/dom/navigate-encode-params-test.tsx @@ -93,4 +93,44 @@ describe("navigate with params", () => { expect(node.innerHTML).toMatch(/react\+router/); }); }); + + describe("when navigate params are encoded using #", () => { + it("the encoding of the # parameter in the URL has been changed", () => { + function Start() { + let navigate = useNavigate(); + + React.useEffect(() => { + navigate("/route/react%23router/subroute/router/blog"); + }); + + return null; + } + + function Blog() { + let params = useParams(); + return

Blog: {params.routeName}-{params.subrouteName}

; + } + + act(() => { + ReactDOM.createRoot(node).render( + + + } /> + + } /> + + + } /> + + + ); + }); + + let pathname = window.location.pathname; + expect(pathname).toEqual("/route/react%23router/subroute/router/blog"); + + expect(node.innerHTML).toMatch(/react#router-router/); + }); + }); }); diff --git a/packages/react-router/lib/router/history.ts b/packages/react-router/lib/router/history.ts index e7e07ac28b..fd17b3e608 100644 --- a/packages/react-router/lib/router/history.ts +++ b/packages/react-router/lib/router/history.ts @@ -695,6 +695,7 @@ function getUrlBasedHistory( // pre-encode them since they might be part of a matching splat param from // an ancestor route href = href.replace(/ $/, "%20"); + href = typeof to === "string" ? href.replace(/#/, "%23") : href invariant( base, `No window.location.(origin|href) available to create URL for href: ${href}`