vercel / next.js

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

NextJS 13 breaks cross-tab animation navigation #55308

Closed zbraniecki closed 1 year ago

zbraniecki commented 1 year ago

Link to the code that reproduces this issue or a replay of the bug

https://github.com/zbraniecki/nextjs13-mui-tabs-navigation-demo

To Reproduce

  1. Start the application
  2. Try to navigate between tabs

Current vs. Expected behavior

Currently, the tab switch animation breaks because the whole page reloads.\

Expected result is smooth animation, like in older version of Next

Verify canary release

Provide environment information

…/mui-demo(main)〉npx --no-install next info

    Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000
    Binaries:
      Node: 20.5.1
      npm: 9.8.0
      Yarn: 1.22.19
      pnpm: 8.6.12
    Relevant Packages:
      next: 13.4.19
      eslint-config-next: 13.4.19
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

warn  - Latest canary version not detected, detected: "13.4.19", newest: "13.4.20-canary.26".
        Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
        Read more - https://nextjs.org/docs/messages/opening-an-issue

Which area(s) are affected? (Select all that apply)

Routing (next/router, next/navigation, next/link)

Additional context

I suspect that it has something to do with how nextjs 13 doesn't do shallow hydration on page navigation.

zbraniecki commented 1 year ago

Expected result: https://github.com/vercel/next.js/assets/449986/83ad1ba7-5140-4612-a250-1e4388d4b8d5

Current result:

https://github.com/vercel/next.js/assets/449986/6922d0d4-5291-4091-801f-8a574455cd70

l-you commented 1 year ago

This behavior is expected. During navigation, everything within the page.tsx file is unmounted. If you wish to maintain state (or in this instance, maintain the animation), the buttons "Item 1" and "Item 2" should reside in the layout.tsx file. Layouts do not unmount when different URLs for the same navigation fragment are rendered.

Refer to the Next.js documentation for more details:

When navigating from /dashboard/settings to /dashboard/analytics, page.tsx in /dashboard/analytics will be rendered on the server because it is UI that changed, while dashboard/layout.tsx will not be re-rendered because it is a common UI between the two routes.

Based on the Next.js directory semantics, the content you render under "Item one" should be in the page.tsx component. Meanwhile, all three buttons that alter the URL state should be in the layout.tsx component.

It is common practice to use layout.tsx for single page.tsx file.

zbraniecki commented 1 year ago

Thanks. I was able to reproduce the proper behavior with src/app/layout.tsx.

But when I updated to subfolder src/app/foo/layout.tsx I'm seeing the broken behavior again.

Here's the diff: https://github.com/zbraniecki/nextjs13-mui-tabs-navigation-demo/commit/c31e968e390cdd87c66c04be3e41fed5d28d3a2d

l-you commented 1 year ago

But when I updated to subfolder src/app/foo/layout.tsx I'm seeing the broken behavior again.

I've reviewed your setup and I'd like to point out a few adjustments that might resolve the issue based on the official documentation:

  1. Your reproduction seems to be missing the root layout component. According to the Next.js documentation, this component is mandatory.
  2. Since you are catching all sub-routes with [[...id]], the layout.tsx will be unmounted every time the parent path fragment params changes. Place your nested layout.tsx in the 'foo' folder

For clarity, your directory structure should resemble the structure shown in the following screenshot:

Screenshot 2023-09-13 at 14 45 24
zbraniecki commented 1 year ago

Hi @rusted-love . Thanks for feedback. I applied the feedback and it still doesn't work. My current suspicion is that src/app/layout.tsx indeed doesn't reload on url change, but src/app/foo/layout.tsx does reload even when the new url is leading to the same /foo/* subdirectory.

l-you commented 1 year ago

@zbraniecki

I cloned your repository to the CodeSandbox. Everything works as expected. Tested with MacOS Safari and Google Chrome. Please take a look at CodeSandbox reproduction. Animation works as expected.

https://github.com/vercel/next.js/assets/32598874/e6eb16e4-f9b5-415b-a5ad-09c81acd6f4c

zbraniecki commented 1 year ago

I can confirm that the latest version actually fixes my issue, both in minimized testcase and in actual app!

Thank you for your patience and support. Closing this issue.

github-actions[bot] commented 1 year ago

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