Next.js 14拦截与并行路由模态框刷新404问题求助
Next.js 14 App Router模态框刷新后404错误解决
我最近在用Next.js 14的App Router开发社交网站,核心功能包括展示用户帖子和评论。为了复现问题,我做了简化示例(忽略样式):
- 根
page.tsx:显示页面标题,提供跳转首页的按钮 - 首页
home/page.tsx:显示页面标题,点击按钮打开模态框,此时URL变为/compose/post - 平行路由
@modal/(.)compose/post/page.tsx:模态框内容,带关闭按钮返回首页
目前模态框正常打开,但在/compose/post路径下刷新页面会触发404错误。尝试添加返回null的default.tsx后问题依旧。
当前文件结构
src/ app/ @modal/ default.tsx .(compose)/ post/ page.tsx default.tsx home/ page.tsx default.tsx globals.css layout.tsx page.tsx
相关代码
src/app/page.tsx
"use client"; import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); const handleOnClick = () => { router.push("home"); }; return ( <> <div>I am the root page</div> <button style={{ background: "blue" }} onClick={handleOnClick}> Go to homepage </button> </> ); }
src/app/layout.tsx
import type { Metadata } from "next"; import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { title: "Intercepting and Parallel Routes", description: "Experimenting", }; export default function RootLayout({ children, modal, }: { children: React.ReactNode; modal: React.ReactNode; }) { return ( <html lang="en"> <body className={inter.className}> {modal} {children} </body> </html> ); }
src/app/default.tsx
import Page from "./page"; export default Page;
src/app/home/page.tsx
"use client"; import { useRouter } from "next/navigation"; export default function Home() { const router = useRouter(); const handleOnClick = () => { router.push("compose/post"); }; return( <> <div>I am the homepage</div> <button style={{ background: "blue" }} onClick={handleOnClick}> Open modal </button> </> ) }
src/app/@modal/page.tsx
export default function Page() { return null; }
src/app/@modal/default.tsx
export default function Default() { return null; }
src/app/@modal/(.)compose/post/page.tsx
"use client"; import { useRouter } from 'next/navigation'; export default function ComposePost() { const router = useRouter(); const handleClose = () => { router.back(); }; return( <> <div>I am the modal</div> <button style={{background: 'green'}}onClick={handleClose}>Close</button> </> ) }
问题原因及解决方法
问题出在文件结构:你把compose/post放在了.(compose)目录下,但拦截路由的逻辑要求,当浏览器直接请求/compose/post时,Next.js需要找到对应的路由文件。当前结构下没有这个路径的page.tsx,所以刷新会404。
修正步骤
- 删除根
app目录下的.(compose)文件夹 - 在
app目录下直接创建compose/post文件夹,添加page.tsx文件。这里有两种处理方式:- 方式一:刷新后重定向到首页
// src/app/compose/post/page.tsx import { redirect } from 'next/navigation'; export default function ComposePostPage() { redirect('/home'); } - 方式二:刷新后保留模态框+首页内容
如果希望刷新后依然显示首页+模态框,可以让这个page.tsx渲染首页内容,确保平行路由的模态框正常加载:// src/app/compose/post/page.tsx import Home from '../../home/page'; export default function ComposePostPage() { return <Home />; }
- 方式一:刷新后重定向到首页
- 确保
@modal/(.)compose/post/page.tsx路径保持不变,这个文件负责在拦截路由时渲染模态框。
修改后,刷新/compose/post路径时,Next.js会加载app/compose/post/page.tsx,同时平行路由@modal会渲染对应的模态框组件,解决404问题。
内容的提问来源于stack exchange,提问作者LAQ
相关产品推荐
相关产品推荐

