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

Next.js滚动动态更新URL出现404问题求解决方案

滚动动态更新URL解决404问题方案

1. 先搞定路由配置,不然肯定404

Next.js的路由是文件系统驱动的,你要访问/home/components/1这类路径,就得有对应的路由文件匹配,不然服务器端直接返回404。分两种路由模式配置:

用Pages Router(Next.js 12及更早)

在pages/home/components/目录下创建[id].js文件,直接复用原components.js的逻辑即可,或者简单导入:

// pages/home/components/[id].js
import ComponentsPage from './components';

export default ComponentsPage;

// 若组件ID是动态生成的,添加以下代码支持动态路径
export async function getStaticPaths() {
  return {
    paths: [], // 无需预生成所有路径则留空
    fallback: true,
  };
}

export async function getStaticProps({ params }) {
  return {
    props: { componentId: params.id }, // 可选:把ID传给页面组件使用
  };
}

用App Router(Next.js 13+)

在app/home/components/目录下创建[id]/page.js,复用原page.js的内容:

// app/home/components/[id]/page.js
import ComponentsPage from '../page';

export default function ComponentDetailPage({ params }) {
  return <ComponentsPage componentId={params.id} />;
}

2. 修正滚动时的路由跳转逻辑

你之前的router.push用法有误,需要添加shallow: true参数,同时避免重复触发跳转:

const handleScroll = () => {
  const baseHeaderPositions = baseHeaderRefs.current.map((ref) => {
    const bounding = ref?.getBoundingClientRect();
    if (!bounding) return { top: Infinity, bottom: Infinity };
    return { top: bounding.top, bottom: bounding.bottom };
  });

  const topBaseHeaderIndex = baseHeaderPositions.findIndex(
    ({ top, bottom }) => top < window.innerHeight && bottom > 64,
  );

  if (topBaseHeaderIndex >= 0) {
    setTopBaseHeaderIndex(topBaseHeaderIndex);
    const componentId = baseHeaderDataArr[topBaseHeaderIndex]?.id || "";
    // 去掉当前URL末尾可能存在的ID,避免重复拼接
    const currentBasePath = router.asPath.split('/').slice(0, -1).join('/');
    const targetUrl = componentId ? `${currentBasePath}/${componentId}` : currentBasePath;

    // 仅当目标URL与当前URL不同时才跳转,防止滚动时频繁触发
    if (router.asPath !== targetUrl) {
      router.push(targetUrl, undefined, { shallow: true });
    }
  }
};

useEffect(() => {
  // 添加passive:true优化滚动性能
  window.addEventListener("scroll", handleScroll, { passive: true });

  return () => {
    window.removeEventListener("scroll", handleScroll);
  };
}, [router, baseHeaderDataArr]);

3. 核心要点说明

  • Shallow Routing的作用:shallow: true让Next.js仅更新URL,不会重新加载页面组件,也不会触发服务器端的数据获取逻辑,完全适配滚动时的URL更新场景。
  • 路由配置的必要性:即便用了shallow路由,用户刷新页面或直接访问带ID的URL时,服务器需要匹配到对应的路由,否则仍会返回404,因此动态路由文件必须创建。
  • 避免重复跳转:增加URL判断逻辑,防止滚动过程中频繁调用router.push,既优化性能也避免潜在问题。

内容的提问来源于stack exchange,提问作者Malith Dilshan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:23:13