Next.js+Strapi新增产品页面生产环境404问题求助
Next.js + Strapi 生产环境新增产品详情页404问题解决
问题概述
- 站点基于Next.js + Strapi CMS搭建,开发模式无异常
- 生产环境中,产品目录新增产品后列表页显示正常,但点击进入详情页触发404错误
- 重新构建Next.js并部署后,新增产品的详情页可正常访问
相关代码与配置
1. blank/[slug].js 页面代码
export async function getStaticPaths() { const blanksRes = await fetchAPI("/blanks", { fields: ["slug"] }); return { paths: blanksRes.data.map((blank) => ({ params: { slug: blank.attributes.slug, }, })), fallback: false, }; } export async function getStaticProps({ params }) { const blanksRes = await fetchAPI("/blanks", { filters: { slug: params.slug, }, populate: ["*", "slug"], }); return { props: { blank: blanksRes.data[0], }, revalidate: 1, }; }
2. Card组件代码
const Card = ({ blank }) => { <Link key={blank.id} href={`/blank/${blank.attributes.slug}`} > ... </Link> }
3. next.config.js 配置
output: "standalone"
4. getStrapiURL 函数代码
export function getStrapiURL(path = "") { return `${ process.env.NEXT_PUBLIC_STRAPI_API_URL || "http://172.17.0.5:1337" }${path}`; }
5. Dockerfile配置
FROM node:16-alpine AS deps RUN apk add --no-cache libc6-compat WORKDIR /app COPY package*.json ./ RUN npm ci --only=production FROM node:16-alpine AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . RUN npm run build --force FROM node:16-alpine AS runner WORKDIR /app ENV NODE_ENV production ENV NEXT_SHARP_PATH=/tmp/node_modules/sharp RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public COPY --from=builder /app/package.json ./package.json COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static USER nextjs EXPOSE 80 ENV PORT 80 CMD ["node", "server.js"]
解决方案
1. 修改getStaticPaths的fallback参数
当前fallback: false意味着只有构建时从Strapi获取的slug对应的页面会被预生成,新增产品的slug不在构建时的列表中,访问时自然触发404。
方案A:使用fallback: 'blocking'(推荐)
访问未预生成的路径时,Next.js会在服务器端动态生成该页面,生成后缓存,后续访问直接使用缓存:
export async function getStaticPaths() { const blanksRes = await fetchAPI("/blanks", { fields: ["slug"] }); return { paths: blanksRes.data.map((blank) => ({ params: { slug: blank.attributes.slug, }, })), fallback: 'blocking', // 修改此处 }; }
方案B:使用fallback: true
先返回加载状态页面,后台异步生成目标页面,适合需要即时响应的场景,但需处理加载状态:
export async function getStaticPaths() { const blanksRes = await fetchAPI("/blanks", { fields: ["slug"] }); return { paths: blanksRes.data.map((blank) => ({ params: { slug: blank.attributes.slug, }, })), fallback: true, // 修改此处 }; }
同时在页面组件中添加加载状态处理:
import { useRouter } from 'next/router'; export default function BlankPage({ blank }) { const router = useRouter(); // 页面正在生成中时显示加载状态 if (router.isFallback) { return <div>加载中...</div>; } // 正常渲染页面内容 return ( <div> {/* 产品详情内容 */} </div> ); }
2. 修正Strapi API地址配置
生产环境中,Next.js容器应通过Strapi的公开域名(https://strapi.domainname.com)访问API,而非容器内部IP:
export function getStrapiURL(path = "") { return `${ process.env.NEXT_PUBLIC_STRAPI_API_URL || "https://strapi.domainname.com" // 替换为你的Strapi生产域名 }${path}`; }
并确保Docker运行时正确传递环境变量:
docker run -e NEXT_PUBLIC_STRAPI_API_URL=https://strapi.domainname.com [你的镜像名]
3. 验证Strapi CORS配置
在Strapi后台设置 > 全局设置 > CORS中,添加Next.js生产域名到允许的源列表,避免API访问被拦截。
内容的提问来源于stack exchange,提问作者Nick Shlyapin
相关产品推荐
相关产品推荐

