vercel / next.js

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

Investigate delaying asPath values for all build-time exported pages #17143

Open ijjk opened 4 years ago

ijjk commented 4 years ago

When a page is exported at build time from either the automatic static optimization or from leveraging getStaticProps the asPath will initially be the pathname since it is the information we have for what the URL should be when visiting the page.

On the client we currently delay updating the asPath for dynamic pages that leverage the automatic static optimization to prevent a hydration mismatch. We should investigate applying this behavior for all build-time exported pages since they can all encounter a hydration mismatch if rewritten to using the rewrites feature and asPath is used while rendering the page.

Original issue opened here https://github.com/vercel/next.js/issues/17113 which was initially thought to be related to GS(S)P asPath resolving but is not since the reproduction provided only leverages pages that are automatically statically optimized without GS(S)P methods.

nghiepdev commented 4 years ago

@ijjk Any update? I had tried the latest 9.5.6-canary-12 version but the issue is still.

I think this is a big problem with the rewrites feature.

https://codesandbox.io/s/sharp-cannon-kcsio?file=/pages/post.js

ijjk commented 4 years ago

@nghiepit this would be more of an optimization to help users prevent from accidentally breaking hydration and requires discussion before addressing.

To avoid this from breaking hydration currently you should wait to use the asPath value while rendering until after the page/component has mounted e.g. useEffect(() => {}, [])

Regaddi commented 3 years ago

Hey,

I am facing this issue, too, but unfortunately useEffect(() => {}, []) does not resolve the issue for me. asPath keeps returning the pathnames value (at least) for the first client-side render cycle.

Here's a Codesandbox with some console.log statements to demonstrate the issue: https://codesandbox.io/s/little-wave-747j2?file=/pages/users/%5Bid%5D.js

In order to reliably read asPath there's some custom code needed, e.g.

useEffect(() => {
  if (asPath.includes('[')) return
  // use asPath
}, [asPath])

but that adds friction on cross-page components.

nghiepdev commented 3 years ago

Hi @ijjk

If asPath incorrect on the server-side this is bad news for SEO.

Some meta tags will be affected: og:url, rel:canonical, ... It will very difficult to calculate the URL correctly without the asPath.

<meta property="og:url" content="https://domain.com/my-post-1.html" />
ijjk commented 3 years ago

If asPath incorrect on the server-side this is bad news for SEO

@nghiepit this issue doesn't address that, we can't know the end asPath value for automatically statically optimized pages at build time unless you use getStaticProps with getStaticPaths