next.js icon indicating copy to clipboard operation
next.js copied to clipboard

`next/link` does not format the URL string properly with URL object for a dynamic route.

Open jpnws opened this issue 2 years ago • 3 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js 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: 18.12.1
  npm: 9.1.1
  Yarn: N/A
  pnpm: N/A
Relevant packages:
  next: 13.0.3-canary.2
  eslint-config-next: 13.0.2
  react: 18.2.0
  react-dom: 18.2.0

What browser are you using? (if relevant)

Chrome 107.0.5304.87 (Official Build) (arm64)

How are you deploying your application? (if relevant)

next dev and next start

Describe the Bug

Based on NextJS beta and stable docs:

  • https://beta.nextjs.org/docs/api-reference/components/link#href
  • https://nextjs.org/docs/api-reference/next/link#with-url-object

A URL object can be used inside Link in the following way.

<Link
  href={{
    pathname: '/blog/[slug]',
    query: { slug: 'my-post' },
  }}
>

Which will generate a link to /blog/my-post.

However, it instead generates a link to /blog/[slug]?slug=my-post.

Expected Behavior

Link should generate a link to /blog/my-post.

Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster

https://stackblitz.com/edit/vercel-next-js-s8tr8n?file=app/page.tsx

To Reproduce

  1. Create a new app with npx create-next-app@latest --experimental-app.
  2. Add the following code to app/page.tsx.
<Link href={{ pathname: "/blog/[slug]", query: { slug: "my-post" } }}>
  Hyperlink
</Link>
  1. Create app/blog/[slug]/page.tsx and add the following code to it.
export default function Page({ params }: { params: { slug: string } }) {
  const { slug } = params;
  return (
    <div>
      <h1>{slug}</h1>
    </div>
  );
}

  1. Run the server and visit the 'Hyperlink` from the main page and check out the URL.

jpnws avatar Nov 10 '22 01:11 jpnws

I am confirming that I am seeing the same issue.

ianizaguirre avatar Nov 14 '22 22:11 ianizaguirre

The new router no longer has a concept of dynamic segments vs non dynamic segments client-side, it also solves the query vs params issue that has come up before, basically query no longer holds the dynamic segments.

Something like this will work:

<Link href={{ pathname: "/blog/my-post" }}>
  Hyperlink
</Link>

We'll have to add an error when a dynamic segment is referenced in this way in development for app @hanneslund.

timneutkens avatar Nov 15 '22 09:11 timneutkens

The new router no longer has a concept of dynamic segments vs non dynamic segments client-side, it also solves the query vs params issue that has come up before, basically query no longer holds the dynamic segments.

Something like this will work:

<Link href={{ pathname: "/blog/my-post" }}>
  Hyperlink
</Link>

We'll have to add an error when a dynamic segment is referenced in this way in development for app @hanneslund.

So does that mean this setup in the following example will not work anymore? :

// an object in a constants file that i import into the component
const routes = {
  overview: {
    path: '/risk-rules/[id]',
  }
}



const { id } = router.query


<Button
  onClick={() => router.push({
    pathname: routes.overview.path,   // < ----
    query: { id },                                       // <----
  })}
/>

So what would the best practice be now to make it equivalent? would it be just writing it as a template literal or something else? Because its not as nice to share my paths with other files doing it as a template literal:

<Button
  onClick={() => router.push({
    pathname:  `/risk-rules/${id}`,
  })}
/>

ianizaguirre avatar Nov 15 '22 15:11 ianizaguirre

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Dec 26 '22 00:12 github-actions[bot]