Bentasy
Bentasy

Reputation: 168

Link component interpolation error nextjs

I am getting this error in Next.js:

Error: The provided 'href' (/subject/[subject]) value is missing query values (subject) to be interpolated properly. Read more: https://err.sh/vercel/next.js/href-interpolation-failed`.

I have a dynamic page set up as /subject/[subject].tsx. Now in my navigation I have:

<Link href={'/subject/${subject}'} passHref><a>{subject}</a></Link>

It works fine when I access the page with different paths but when I am pressing on a button on the page it throws the error above which I imagine is because the component rerenders. If you go to the page in the error it says: Note: this error will only show when the next/link component is clicked not when only rendered.

I have tried to look for a solution and I tried doing:

<Link href={{pathname: '/subject/[subject]', query: {subject: subject}}}></Link>

but nothing changed. I read the docs and it seems that the as prop is only an optional decorator that is not used anymore so I fail to see how that can help me.

Upvotes: 13

Views: 16821

Answers (6)

Tam La
Tam La

Reputation: 33

try add this function, it work for me:

export async function getServerSideProps(context) {
return {
props: {},
};
}

Upvotes: 0

Aras Ors
Aras Ors

Reputation: 1

I was having the same problem, this is how I solved it.

While pushing something to the router, we need to give the old values ​​in it.

In that:

const router = useRouter()

router.push({
   ...router,
   pathname: '/your-pathname'
})

Upvotes: 0

Aleks Barylo
Aleks Barylo

Reputation: 141

I got the same issue when trying to redirect user to locale. I did it in useEffect. After investigate I discovered that on first render router.query is empty, so it's missing required field id. I fix it by using router.isReady

export const useUserLanguageRoute = () => {
  const router = useRouter()

  useEffect(() => {
    const {
      locales = [],
      locale,
      asPath,
      defaultLocale,
      pathname,
      query,
      isReady // here it is
    } = router

    const browserLanguage = window.navigator.language.slice(0, 2)

    const shouldChangeLocale =
      isReady && // and here I use it
      locale !== browserLanguage
      && locale === defaultLocale
      && locales.includes(browserLanguage)

    if (shouldChangeLocale) {
      router.push(
        {
          pathname,
          query,
        },
        asPath,
        { locale: browserLanguage }
      )
    }
  }, [router])
}

Upvotes: 6

Juanma Menendez
Juanma Menendez

Reputation: 20129

Another possible solution could be redirect using the router.push function:

const myRedirectFunction = function () {

    if (typeof window !== 'undefined') {
        router.push({
            pathname: router.pathname,
            query: {...router.query, myqueryparam: 'myvalue'},
        })
    }

}


return (
  <>
    <button onClick={() => {myRedirectFunction()}}> Continue </button>
  </>

)

It is important to include ...router.query because there is where the [dynamic] current value is included, so we need to keep it.

Reference: https://github.com/vercel/next.js/blob/master/errors/href-interpolation-failed.md

Upvotes: 4

alfrednoble
alfrednoble

Reputation: 89

@Bentasy, Like you rightly pointed out, any re-render of the page is expecting you to pass in the dynamic route params again. The way I avoided page re-rendering with subsequent clicks on the page was to replace Link tag on the page with a label tag. I was using the Next Link tag to navigate between the tabs on this image which generated this same error. So I replaced the Link tags with label tags and the error was solved. The tabs on the page.

Upvotes: 0

user3069270
user3069270

Reputation: 52

You better do a null || undefined check in prior.

Upvotes: 0

Related Questions