react-router icon indicating copy to clipboard operation
react-router copied to clipboard

[Bug]: "Failed to construct 'URL': Invalid URL" error when using lazy loading and double slash in URL

Open mskrzypek opened this issue 1 year ago • 3 comments

What version of React Router are you using?

6.21.2

Steps to Reproduce

  1. Prepare routing with lazy loaded component at root path:

    createBrowserRouter([
       {
         path: "/",
         lazy: async () => {
           const { Slash } = await import("./components");
           return {
             Component: () => <Slash />,
           };
         },
       },
    ]);
    
  2. Open app in browser with additional slash at the end of the URL, ie. http://localhost:3000//

Expected Behavior

Lazy loaded component is rendered at root URL, even though there are two slashes in the URL.

Actual Behavior

Lazy loaded component is not loading, there is Failed to construct 'URL': Invalid URL error. When component is rendered with element, it is being rendered correctly.

I prepared a reproduction example: https://codesandbox.io/p/sandbox/blissful-ritchie-9szrnk

mskrzypek avatar Jan 12 '24 19:01 mskrzypek

unfortunately, i have the same problem, is there any solution?

fillinmar avatar Apr 04 '24 15:04 fillinmar

Looks like a duplicate of #11429

@mskrzypek if it helps I investigated that one slightly. It looks like official URL spec that <host>// should not be a valid URL. You wrote in Expected behavior that the Slash component should get rendered at the root. Why do you expect that in the // route? I am asking as it looks like a nested route to me if anything.

hjonasson avatar May 06 '24 01:05 hjonasson

Looks like a duplicate of #11429

@mskrzypek if it helps I investigated that one slightly. It looks like official URL spec that <host>// should not be a valid URL. You wrote in Expected behavior that the Slash component should get rendered at the root. Why do you expect that in the // route? I am asking as it looks like a nested route to me if anything.

@hjonasson Thank you for your investigation.

I believe, this is not a duplicate of #11429. Please refer to the reproduction example, which clearly explains the problem. When we use the element prop in Route, the double slash in the root route is handled, but when we use lazy, it is not. However, in non-root routes, both element and lazy handle doubled routes.

Regardless of the URL specification, it is a very popular convention to handle doubled slashes in URLs, and I think it is not uncommon for users to mistakenly enter two slashes instead of one in a URL. If one could perform some benchmarks, it turns out that in most solutions, double slashes are converted to single slashes, e.g.

  • https://nextjs.org//showcase
  • https://kit.svelte.dev//docs/introduction
  • https://angular.io//resources?category=community
  • https://vuejs.org//api

mskrzypek avatar May 16 '24 19:05 mskrzypek