You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目画廊单个项目路由跳转404问题排查

Next.js 项目画廊动态路由404问题解决

问题场景

用Next.js开发项目画廊,点击项目卡片跳转到对应详情页,数据由data.js提供,创建了[id].js动态路由文件,通过useRouter()实现路由,但点击后出现404错误。

当前文件结构

└─ project
   ├─ app
   │  ├─ components
   │  │  └─ projects.js
   │  ├─ data.js
   │  ├─ globals.css
   │  ├─ layout.js
   │  ├─ page.js
   │  ├─ pages
   │  │  ├─ project-one.js
   │  │  ├─ project-two.js
   │  │  ├─ project-three.js
   └─

现有代码

[id].js

import { useRouter } from "next/router";
import { projects } from "../../data";

const ProjectPage = () => {
  const router = useRouter();
  const { id } = router.query;

  const project = projects.find((project) => project.id === id);

  if (!project) {
    return <div>Project not found</div>;
  }

  return (
    <div>
      <h1>{project.title}</h1>
      <p>{project.description}</p>
      <img src={project.image} alt={project.title} />
      <p>{project.tags}</p>
    </div>
  );
};

export default ProjectPage;

Projects.js

import React from "react";
import Link from "next/link";
import { projects } from "../data";

export default function Projects() {
  return (
    <section id="projects">
      <div>
        <div>
          <h1>
            My Projects
          </h1>
        </div>
        <div>
          {projects.map((project) => (
            <Link
              href={`/${project.id}`}
              key={project.image}
            >
              <div>
                <img
                  alt="Project"
                  src={project.image}
                />
                <div>
                  <h1>
                    {project.title}
                  </h1>
                  <p>{project.description}</p>
                  <p> {project.tags} </p>
                </div>
              </div>
            </Link>
          ))}
        </div>
      </div>
    </section>
  );
}

data.js

export const projects = [
  {
    id: "identifier",
    title: "#",
    description:
      "#",
    image: "#",
    link: "../app/pages/project-one.js",
    tags: "#",
  },
];

问题原因及修复步骤

1. 路由系统混用(核心问题)

你当前混合了Next.js的App Router(app目录)和Pages Router(pages目录),两种路由系统不能共存。既然已经用了app目录,就统一遵循App Router规则:

  • 删除app/pages目录(里面的project-one.js等文件已无用)
  • 动态路由文件必须放在app目录下,结构为app/[路由前缀]/[id]/page.js,比如创建app/projects/[id]/page.js

2. 动态路由参数获取方式错误

App Router中不能使用next/router的useRouter,推荐直接通过params参数获取动态id。修改后的app/projects/[id]/page.js:

import { projects } from '../../data';

export default function ProjectPage({ params }) {
  const project = projects.find(item => item.id === params.id);

  if (!project) {
    return <div>项目未找到</div>;
  }

  return (
    <div>
      <h1>{project.title}</h1>
      <p>{project.description}</p>
      <img src={project.image} alt={project.title} />
      <p>{project.tags}</p>
    </div>
  );
}

3. Link跳转路径错误

Projects组件中的Link跳转路径要和动态路由的实际路径对应,修改href为/projects/${project.id},同时把key改成唯一稳定的project.id(不要用image路径):

import React from "react";
import Link from "next/link";
import { projects } from "../data";

export default function Projects() {
  return (
    <section id="projects">
      <div>
        <div>
          <h1>我的项目</h1>
        </div>
        <div>
          {projects.map((project) => (
            <Link
              href={`/projects/${project.id}`}
              key={project.id}
            >
              <div>
                <img
                  alt="项目展示图"
                  src={project.image}
                />
                <div>
                  <h1>{project.title}</h1>
                  <p>{project.description}</p>
                  <p>{project.tags}</p>
                </div>
              </div>
            </Link>
          ))}
        </div>
      </div>
    </section>
  );
}

4. 清理无用数据字段

data.js中的link字段是本地文件路径,完全无用,直接删除;同时把id改成和实际项目对应的标识(比如project-one):

export const projects = [
  {
    id: "project-one",
    title: "项目一",
    description: "项目一的详细描述",
    image: "/images/project-one.jpg", // 替换为实际图片路径
    tags: "React, Next.js",
  },
  // 其他项目数据...
];

关键注意事项

  • 始终保持路由系统统一,要么用App Router(app目录),要么用Pages Router(pages目录)
  • App Router的动态路由必须遵循app/路径/[参数]/page.js的命名规则
  • 列表渲染的key必须是唯一且稳定的值,优先用数据id而非图片路径

内容的提问来源于stack exchange,提问作者Freddie Heath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:13:13