next.js: [NEXT-1144] Parallel Routes do not apply individual `loading.tsx` as described in documentation

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 16.19.1
      npm: 8.19.3
      Yarn: 1.22.19
      pnpm: 7.3.0
    Relevant packages:
      next: 13.3.5-canary.12
      eslint-config-next: 13.4.0
      react: 18.2.0
      react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true), Routing (next/router, next/navigation, next/link)

Link to the code that reproduces this issue

https://github.com/brunocangs/next-app-parallel-issue

To Reproduce

Run the project with yarn dev and navigate to http://localhost:3000

Describe the Bug

When using Parallel Routes (e.g. /app/@slot/page.tsx), the @slot’s loading.tsx states are never called or displayed.

The current beahviours observed even differ in dev and prod, as seen in the videos references.

Prod Link: https://next-app-parallel-issue.vercel.app/

Dev behaviour:

  • Layout displays:
    • First slot (@slot/page.tsx) is async, so it displays a loading state. However this is the page’s loading state, not the slot loading state.
    • Second slot is not async, so it immediately displays. The Suspended component displays it’s loading state correctly
  • Suspended component on second slots loads
  • Eventually First slot loads and displays it’s suspended component correctly.
  • Suspended component on first slot loads

https://user-images.githubusercontent.com/30100875/236318280-294f6a0f-1809-4756-bdd1-da1ca7f2d792.mov

Prod behaviour:

  • Everything gets server loaded and awaited. The parts that would require basic suspending get optimized and no loading states are displayed.

I didn’t include a prod video as it would only be a page reload

Expected Behavior

It is expected that, as mentioned in the documentation, the loading state for each of the slots will be correctly displayed per the image below image

Which browser are you using? (if relevant)

Chrome

How are you deploying your application? (if relevant)

Vercel

NEXT-1144

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 45
  • Comments: 34 (4 by maintainers)

Most upvoted comments

Hey @timneutkens, could we have an estimate of timeline on this feature, please?

Screenshot 2023-06-18 at 15 10 04

It shouldn’t be in the docs if you can’t currently do what the docs are demonstrating (without resorting to a work around).

Yes. In this case the documentation is not describing the current behavior and is misleading. The loading and error components are being applied as follows:

image

image

Seems that the root loading and error components are applied separately to each parallel route. This is inconvenient as precisely the goal of parallel routing is being able to manage separate parts of the UI that are not related with each other at the same time.

Cannot confirm that it works for me on 13.4.7 with default.tsx present 😦 So I don’t think the issue is completely resolved unfortunately

You can temporarily put it in a route group app/@something/(myroutegroup)/loading.tsx.

Still encountering this error on v13.5^ This routing method works correctly in 13.4.7 but it seems the bug has re-appeared in 13.5^.

Hoping for a fix soon 😦

FWIW in my testing using a default state (i.e. default.jsx) in a parallel route also doesn’t trigger a loading state, even with the temporary route group fix that @timneutkens suggested.

Hi all – the original reproduction in this thread seems to be behaving correctly (testing against the latest Next.js canary).

For those commenting on the loading state not appearing in production builds: the examples that have been shared indicate that your pages can be statically generated (learn more about dynamic rendering here). In other words, at build time, Next.js is prefetching your routes and generating static HTML. Once served to the user, since the page could be completely statically generated, there’s no need to rendering a loading boundary as there’s nothing to wait for.

If anyone is still running into problems here, please open a new issue with a minimal reproduction and we’ll take a look. As the original reproduction shared in this issue is now working, I’m going to close this.

I’m having the same issue but with layout.tsx. I had to apply the solution on https://github.com/vercel/next.js/issues/49243#issuecomment-1548111858 of creating a (group) inside each of the parallel routes so that the nested layouts could finally work:

/home
├── @dashboard
│   └── (dashboard)
│        ├── layout.tsx
│        └── page.tsx
├── @login
│   └── (login)
│        ├── layout.tsx
│        └── page.tsx
└─ layout.tsx

I can confirm that #51413 has fixed these issues. 🥳

I’m not sure its fixed since i haven’t had time to check. But they fixed some issues lately https://github.com/vercel/next.js/pull/51413

It seems that error.tsx is also affected?

Also the layout file inside a parallel route is ignored. For example /@team/layout.tsx will not be rendered. With /@team/(__workaround)/layout.tsx it works currently, but it is not optimal to use such hacks.

+1

But wrapping each individual component inside the layout with suspense works as expected.

image

image

This works for me but the loading state is only display at the initial load, when I revalidate the path or call router.refresh(), the loading state is not showing.

And @timneutkens the route group doesn’t work for me on v13.4.2, for neither, both loading.tsx and error.tsx seem to be ignored.

+1

But wrapping each individual component inside the layout with suspense works as expected.

image

image