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

Next.js fallback:true时,提前访问未创建路径后无法生成对应新页面

Next.js fallback:true 下提前访问不存在页面后无法正常渲染新增内容的解决方案

问题背景

我使用getStaticPaths和getStaticProps生成博客页面,为了实现新增页面无需重启服务器即可访问,开启了fallback: true。相关代码如下:

getStaticPaths 代码

export async function getStaticPaths() {
  const paths = ...获取路径的代码...

  return {
    paths: paths,
    fallback: true
  };
}

getStaticProps 代码

export async function getStaticProps({ params }) {
  try {
    const post = await fetchPost(...某个ID...);

    return {
      props: {
        post
      },
      revalidate: 60
    };
  } catch (e) {
    return {
      notFound: true
    };
  }
}

页面组件 fallback 处理代码

const SlugPage: NextPage<any> = props => {
  const theme = useTheme();
  const router = useRouter();

  if (router.isFallback)
    return (
      <Loader
        colors={{
          backgroundColor: theme.colors.earth.second,
          color: theme.colors.earth.fifth
        }}
        loading={true}
      />
    );

    ...页面其余内容...
};

常规场景下,执行yarn build和yarn start后创建新页面/somenewslug,访问时能正常生成内容。但存在边缘问题:若在页面实际创建前就访问/somenewslug,此时getStaticProps返回notFound(当时逻辑正确),但后续创建该页面后,访问仍返回404,即使搭配revalidate也无效。

解决方案

1. 避免返回notFound: true,改用空Props传递

当获取不到文章时,不要返回notFound: true,而是返回props: { post: null }并保留revalidate配置。因为Next.js会缓存notFound的状态,视为永久404,不会再触发重新获取;而返回空Props配合revalidate,会让页面在指定时间后重新执行getStaticProps。

修改后的getStaticProps:

export async function getStaticProps({ params }) {
  try {
    const post = await fetchPost(...某个ID...);
    return {
      props: { post },
      revalidate: 60
    };
  } catch (e) {
    // 不返回notFound,传递空post并保留revalidate
    return {
      props: { post: null },
      revalidate: 60
    };
  }
}

2. 在页面组件中处理空Post的情况

在页面里除了处理router.isFallback,还要判断post是否为null。此时可以显示加载状态,甚至添加定时刷新逻辑,确保文章创建后能及时获取到数据。

修改后的页面组件:

const SlugPage: NextPage<any> = props => {
  const theme = useTheme();
  const router = useRouter();

  if (router.isFallback) {
    return (
      <Loader
        colors={{
          backgroundColor: theme.colors.earth.second,
          color: theme.colors.earth.fifth
        }}
        loading={true}
      />
    );
  }

  // 处理文章尚未创建的情况
  if (!props.post) {
    // 定时刷新页面,触发重新获取数据
    useEffect(() => {
      const timer = setTimeout(() => {
        router.replace(router.asPath);
      }, 30000); // 30秒后刷新
      return () => clearTimeout(timer);
    }, [router]);

    return (
      <Loader
        colors={{
          backgroundColor: theme.colors.earth.second,
          color: theme.colors.earth.fifth
        }}
        loading={true}
      />
    );
  }

  ...页面其余内容...
};

3. 核心原理说明

Next.js中,当getStaticProps返回notFound: true时,这个状态会被持久化缓存,即使设置了revalidate也不会触发重新渲染。而返回包含空数据的Props并保留revalidate,Next.js会在每次请求或到达revalidate时间时,重新执行getStaticProps检查数据是否存在,从而解决提前访问导致的永久404问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:55:38