vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.73k stars 26.62k forks source link

Next.js Link component relative path navigation goes to the wrong path #44568

Open mrob11 opened 1 year ago

mrob11 commented 1 year ago

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000
Binaries:
  Node: 16.18.0
  npm: 8.19.2
  Yarn: 1.22.19
  pnpm: N/A
Relevant packages:
  next: 13.1.2-canary.0
  eslint-config-next: 13.1.1
  react: 18.2.0
  react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Routing (next/router, next/navigation, next/link)

Link to the code that reproduces this issue

https://github.com/mrob11/next-navigation-bug-repro

To Reproduce

Using the hard navigation (i.e. a regular old <a> tag) will correctly navigate to /parent/child-b.

Demo available here: https://next-navigation-bug-repro.vercel.app/

Describe the Bug

Using a path-relative href in the next/link component does not navigate to the same final URL as its regular anchor tag counterpart. Instead it treats the href as if it was a root-relative (e.g. /child-b instead of /parent/child-b).

Expected Behavior

I would expect that using path-relative notation (e.g. ./sibling) would navigate to the same place that the regular anchor tag does.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

vtassios commented 1 year ago

Link creates an <a> tag, so they should have the same result.

Could you provide the page structure of your project and some code about your navigation?

mrob11 commented 1 year ago

There's a repo with a reproduction of the problem linked in the issue description.

A Link component that is provided with the same href value as a regular <a> tag doesn't behave the same way when the href value starts with a ..

A component that uses <a> tags to navigate from /parent/child-a to /parent/child-b using ./child-b as the href value: https://github.com/mrob11/next-navigation-bug-repro/blob/main/app/parent/hard-nav.tsx

A component that uses a <Link> component with the same href value as above will navigate to /child-b instead of /parent/child-b as the regular <a> tag does: https://github.com/mrob11/next-navigation-bug-repro/blob/main/app/parent/soft-nav.tsx

You can see the example deployed here: https://next-navigation-bug-repro.vercel.app/parent/child-a

edgepirate commented 1 year ago

is there any update on this bug.

alvis commented 1 year ago

I'm new to next js and can't believe it has such a low-level issue....

mastoj commented 1 year ago

Seeing the same thing and has also created a small reproduction in this commit: https://github.com/mastoj/nextjs-playground/commit/709485c00ebe8b2222498d1644f26807786a3c75

jeromesth commented 8 months ago

Actually, we had that problem before and we solved it by adding this setting to next.config.js:

 trailingSlash: true

That's how the regular <a> href works. It will use last / in the url path to append the relative path to. So if your page URL path is /my-url and you have a link with a ./my-sub-path or my-sub-path/ (which is equivalent). The browser will append your sub-path to the last / (which is the root of the path in this case) and give you /my-sub-path. Using trailing slashes fixes this and makes sure that the latest / is always at the end of the current path.

You can then go from /my-url/ to /my-url/my-sub-path by using the ./my-sub-path href.

Hope this helps.

steve-marmalade commented 4 months ago

@jeromesth that's very helpful context. In principle, I'm not opposed to making this change, but what's holding me back is that trailing slashes don't seem common across most websites (e.g. I just checked the tabs I have open, and none of github, stackoverflow, figma, react docs, or nextjs docs use trailing slashes). So it would be nice to have support for relative paths without having to opt into a non-standard URL scheme.

long-kr commented 3 months ago

I was testing with component and counter a issue too. I hovered to <Link href={${en}/${products}}> when I was at http://localhost:5134/en/products/. I received this url http://localhost:5134/en/en/products/ which should be http://localhost:5134/en/products/en/products/. Adding trailingSlash: true helped me fix the issue, so not sure if this was intentional.

statusunknown418 commented 3 months ago

has there been any updates on this? really seems like a no-brainer feature for such a big framework

cw1997 commented 1 month ago

Is there any update on this issue? I see it is still required to set trailingSlash to 'true' to fix the problem on Next.js 14.2.5

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!