Next.js项目如何实现预览部署用SSR、生产部署用SSG?
解决方案:根据环境动态切换Next.js的SSG/SSR模式
核心思路
通过条件导出数据获取函数,结合环境变量判断当前部署环境,在生产环境保留SSG(getStaticProps+getStaticPaths)以保证性能,在预览环境切换为SSR(getServerSideProps)缩短构建时间。关键是避免同时导出两种数据获取函数,并复用数据获取逻辑减少冗余。
步骤1:抽离复用的数据获取逻辑
把原本写在getStaticProps里的数据请求逻辑抽成独立函数,让SSG和SSR共用:
// lib/data-fetch.js export async function fetchPageData(params) { // 替换成你实际的数据获取逻辑(API请求/数据库查询等) const res = await fetch(`https://your-api-endpoint.com/content/${params.slug}`); const content = await res.json(); return { props: { content } }; }
步骤2:页面中条件导出数据函数
在页面组件文件中,根据环境变量判断要导出的函数:
// pages/[slug].js import { fetchPageData } from '../lib/data-fetch'; export default function ContentPage({ content }) { // 页面渲染逻辑 return ( <div> <h1>{content.title}</h1> <div dangerouslySetInnerHTML={{ __html: content.body }} /> </div> ); } // 判断预览环境:优先用平台内置变量(如Vercel的VERCEL_ENV),也可自定义环境变量 const isPreview = process.env.VERCEL_ENV === 'preview' || process.env.NEXT_PUBLIC_PREVIEW_DEPLOYMENT === 'true'; if (isPreview) { // 预览环境:导出SSR所需的getServerSideProps export async function getServerSideProps(context) { return fetchPageData(context.params); } } else { // 生产环境:导出SSG所需的getStaticProps和getStaticPaths export async function getStaticProps(context) { return fetchPageData(context.params); } export async function getStaticPaths() { // 原SSG逻辑:获取所有需要预生成的路径 const res = await fetch('https://your-api-endpoint.com/all-slugs'); const slugs = await res.json(); return { paths: slugs.map(slug => ({ params: { slug } })), fallback: false // 根据业务需求调整为true/blocking }; } }
常见报错排查
"Multiple getServerSideProps and getStaticProps exported"
- 原因:环境变量判断逻辑失效,导致两个函数同时被导出。
- 解决:检查预览环境的环境变量是否正确注入(比如Vercel预览部署会自动设置
VERCEL_ENV=preview,无需手动配置);自定义变量需确保构建工具能读取到(如在部署平台的预览构建配置中添加变量)。
环境变量未定义
- 原因:Next.js在构建时未注入环境变量。
- 解决:自定义环境变量需以
NEXT_PUBLIC_开头(如果需要在客户端访问),或在next.config.js中配置env字段;部署平台需在预览环境的变量设置中添加对应项。
语法错误
- 原因:条件导出代码未放在模块顶级。
- 解决:确保
if判断和导出语句在页面文件的顶级作用域,不要嵌套在函数内部。
内容的提问来源于stack exchange,提问作者Tushar Agarwal
相关产品推荐
相关产品推荐

