Search code examples
next.jsnext-router

Nextjs: Is posible to pass object when router.push() using app dir?


I create an Nextjs app using /app dir.

I create multi language for my app, and a button to switch language.

'use client'

import { useParams, usePathname, useRouter } from 'next/navigation'
import { language } from '~/helper/data/common'

function SwitchLang() {

  const router = useRouter()
  const params = useParams()
  const pathname = usePathname()

  console.log(params)

  const localeData = language.find((item) => item.key === params.lang)

  const handleChange = (key: string) => {
    if (key !== params.lang) {
      router.push(pathname, {
        params: {
          ...params,
          lang: key
        }
      })
    }
  }

  return (
    <div
      className="relative border border-common-black px-2 py-1 rounded select-none cursor-pointer"
    >
      <div className="w-6 text-center">{localeData?.label}</div>
        <div className="absolute left-0 top-[calc(100%+2px)] w-full shadow-lg bg-common-white rounded ">
          {language.map((item, index) => (
            <div
              key={index}
              className="px-2 py-1 hover:bg-[#ddd] text-center"
              onClick={() => handleChange(item.key)}
            >
              {item.label}
            </div>
          ))}
        </div>
    </div>
  )
}

export default SwitchLang

Ex: I have a route: /[lang]/product/[id]. In browser: /en/product/3`

I want when change language, the rout change into /vi/product/3.

In nextjs with pages dir. I can do it easily.

But with app dir, new useRouter from next/navigation.

The params when I console.log() is : {lang: 'en', id: '3'}

I try to use

router.push(pathname, {
  params: {
    ...params,
    lang: key
  }
})

but is does not work.


Solution

  • App router does not support push with query params.

    Instead, you want to build the link yourself, for example:

    router.push(`/${key}/product/${params.id}`)