next.js: Parallel / Intercepting Routes rendering 404 on page load

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.4.0: Mon Mar  6 20:59:28 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.13.0
      npm: 9.4.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.3.1-canary.4
      eslint-config-next: 13.3.0
      react: 18.2.0
      react-dom: 18.2.0

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

No response

Link to the code that reproduces this issue

https://vercelnextjsnzcvbl-dh2v--3000--b5037fed.local-credentialless.webcontainer.io/1

To Reproduce

  • Create a Intercepting / Parallel route layout within the app directory
  • Add a modal with a dynamic page (ex: @modal/[id]) with a console log
  • Add a parent page for the same path (ex: [id]) with a console log
  • Attempt to navigate to the dynamic page and see the modal is rendered
  • Refresh the page and see you have a 404 rendered, while the console log for parent page has been called

Describe the Bug

Upon initial client-side navigation to an intercepted route, the page is properly navigated and modal is shown. Upon reloading the page the content is not rendered, get a 404 page but params are still passed.

next-route

Expected Behavior

Navigation should first show modal on initial load from top level page. After reloading the parent page should be loaded, not have 404 but still receive props

The intention is to have a blog page with a list of articles with a set of ids (a,b,c…) which are conditionally rendered in a modal while on the blog page itself, are rendered standalone when visiting from a link / page is reloaded.

blog
├── @modal/[id]
│   └── page.tsx
├── @list
│   └── page.tsx
└── layout.tsx
├── [id]
     └── page.tsx

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 3
  • Comments: 27 (5 by maintainers)

Most upvoted comments

Intercepting and parallel routes seem completely broken to me… or the docs are completely wrong. Either way, this is a very frustrating issue. The group solution did not work for me.

I agree with @jscul on this one, so much of this seems completely broken and half baked. The docs are not correct.

I updated to v13.5.4 and all is still well (running the ‘nextgram’ example).

I removed the “experimental” section from 'next.config.js'.

Now I’ll try adding back in the MUI behavior (piece by piece).

The “trick” to this is to use default.tsx to cover non-matching slots. Adapting the example app worked for my use case

I am having this issue also.

OMG — I think I’ve figured this out!

I was running into the same problem: the intercepted route would load fine when clicking a <Link />; but when I refreshed the page on the intercepted route, it would 404.

Here’s the problem: if the layout slot isn’t filled based on the current path, it will 404. You can test this by removing the slot from the layout file, and then doing a full-page load on the intercepted route path. The full-page load should work just fine now. Then, when you add the slot back to the layout file, it’ll 404 again.

To fix this, you need to use a route group. Remove the slot from your root layout, and create a new layout inside your route group that just renders children and your slot:

// src/app/(home)/layout.tsx
import { ReactNode } from 'react'

export default function Layout({
  children,
  slotNameHere,
}: {
  children: ReactNode
  slotNameHere: ReactNode
}) {
  return (
    <>
      {children}
      {slotNameHere}
    </>
  )
}

Move your homepage and your intercepted routes underneath your route group:

- src
  - app
    - (home)
      - @slotNameHere
        - (.)routeName
          - page.tsx
          - ...etc

Note that, if your intercepted route is a few levels down (e.g., src/app/(home)/@slotNameHere/(.)routeName/foo/bar/page.tsx, you may need to create a page.tsx at the level right under the root of the intercepted route to prevent the same 404 issue (i.e., at src/app/(home)/@slotNameHere/(.)routeName/page.tsx). This can just be an empty component that returns null.

@feedthejim I think there is still something wrong with the (.) selector (https://github.com/vercel/next.js/pull/48276): If you check out this repo: https://codesandbox.io/p/sandbox/nextjs-intercepting-routes-s9j6mo You will see that if you open the blog post, there are two things happening that are off:

  1. It also loads the intercepted page als main page (it replaces the blog page with the item page)
  2. If you have the blog post modal open and refresh the page, it will give you a 404

I modified this repo to use the old (…) syntax here: https://codesandbox.io/p/sandbox/nextjs-intercepting-routes-forked-bfuitc If you try this version (only change is (.) became (..)blog and I also placed everything into a (group)), then everything works as expected.