0

How would one go about linking a button element to a top-level dynamic route, using:

  • NextJS 13.4.9 (using App Router)
  • React/dom 18.2.0

My directory structure is as follows:

app/
- [division]
- - page.tsx
- - [team]
- - - page.tsx
- - - [player]
- - - - page.tsx

Example app/[division]/page.tsx:

// app/[division]/page.tsx

export default function Page({ params }: { params: { division: string } }) {
  return <div>My Division {params.division}</div>;
}

From my understanding after reading the docs, the recommended way to go about his would be to import { useRouter } from 'next/navigation' and use it in the onClick handler, where the button is. For example:

// app/page.tsx

'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/example')}>
      Example
    </button>
  )
}

In this example, the push method expects a string.

But from my understanding, I'd want something like:

router.push({ division: 'northwest' })

And deeper links would look like this:

router.push({ division: 'northwest', team: 'otters', player: 'sammy-slapstick' })

The push method doesn't allow url objects, like the Page Router useRouter function does.

So, how do I link from a button to top-level (and deeper) dynamic links?

Note, this is the ONLY (top-level) dynamic link in my application.

Other stuff:

I attempted to add onClick={() => router.push({ division: "northwest" }), but this didn't work.

  • If the button works like a link, you should be using next/link instead. – Terry Jul 19 '23 at 05:01
  • Thanks @Terry, I tend to agree. However even their examples (pasted above in my OP) use the `onClick()` handler in a button element. – DomainSoil Jul 19 '23 at 12:33

1 Answers1

1

You can use an object with push

See https://nextjs.org/docs/pages/api-reference/functions/use-router#with-url-object

// app/page.tsx

'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button
      type="button"
      onClick={() => {
        router.push({
          pathname: 'app/[division]/page',
          query: { division: whateverTheIdOrSlugIs },
        })
      }}
    >
      Example
    </button>
  )
}
  • 1
    The links and examples you provided were for the Page Router. This doesn't work in the App Router - the element won't even render. `TS2345: Argument of type '{ pathname: string; query: { division: string; }; }' is not assignable to parameter of type 'string'.` – DomainSoil Jul 21 '23 at 12:38
  • 1
    To add to my comment above, the `useRouter` for `next/navigation` only accepts strings, not objects as well like the `next/router` `useRouter` does. https://nextjs.org/docs/app/api-reference/functions/use-router – DomainSoil Jul 21 '23 at 12:42