Next.js动态页SSG路径不存在时降级CSR渲染及fallback参数疑问
关于 fallback 的正确用法
你当前的实现逻辑走了弯路,fallback: true 是 Next.js 增量静态生成(ISR)的原生能力,本身就可以解决「构建后新增文章需要重新构建」的问题,完全不需要自己额外实现 CSR 降级逻辑,你现在写的客户端 useEffect 拉取数据的代码属于冗余实现,还会导致 OG 标签在新文章首次访问时无法正确生成,不符合你的社交分享需求。
你可以按下面的方案修改代码,直接复用 Next.js 原生能力即可:
import React from 'react'; import { useRouter } from 'next/router'; const PostContainer = (props) => { const router = useRouter(); // 未预生成的路径首次访问时,isFallback 为 true,展示加载态即可 if (router.isFallback) { return <div>文章加载中...</div> } // 直接使用 getStaticProps 返回的 props 渲染,无需额外客户端请求 return ( <Post data={props} metaProps={props} /> ); }; // getStaticPaths 你原来的实现不需要修改 export const getStaticPaths = async () => { const list = await getPosts(); if (list?.length) { const paths = list.map((post) => { return { params: { id: post.id, }, }; }); return { paths, fallback: true, }; } return { paths: [], fallback: true, }; }; // getStaticProps 原来的实现也不需要修改,你加的 revalidate:1 已经满足更新需求 export const getStaticProps = async ({ params }) => { const { id } = params; const post = await getPost(id); // 如果文章不存在可以返回 404 if (!post) { return { notFound: true } } const {title, description, previewImage} = post return { props: { title, description, url: `https://sitename./blog/${id}`, image: previewImage, }, revalidate: 1, }; }; export default PostContainer;
如果不想让首次访问新文章的用户看到加载态,你可以把 fallback: true 改为 fallback: 'blocking',首次访问时服务端会先完成页面生成再返回内容,对社交爬虫也更友好,不会爬到加载态的默认元标签。
关于 fallback: true 的触发逻辑
你的理解基本正确:
- 任意用户首次访问未预生成的路径时,Next.js 会在后台运行 getStaticProps 生成静态页面,生成完成后会缓存该页面
- 后续所有用户访问该路径时,都会直接返回已经缓存的静态页面,不会再次触发 getStaticProps
- 你配置的
revalidate: 1会控制缓存的有效期:页面生成后1秒内的请求直接返回缓存内容,超过1秒后收到的新请求,Next.js 会在后台重新运行 getStaticProps 拉取最新的文章数据更新缓存,更新完成后新的请求就会拿到最新的页面内容,不需要重新构建项目。
如果没有配置 revalidate,页面生成后会永久缓存,除非你重新部署项目。
内容的提问来源于stack exchange,提问作者Jeremy Smith
相关产品推荐
相关产品推荐

