
本文详解 next.js 中 `getstaticprops` + `getstaticpaths` 页面无法生成静态 html 源码的根本原因,重点修复 `_app.js` 中的客户端渲染逻辑导致 ssr/ssg 失效的问题,并提供可落地的 seo 友好配置。
你遇到的问题——页面在浏览器中渲染正常,但查看网页源代码(View Page Source)为空白或仅含 ,且禁用 JavaScript 后页面完全不显示——这明确表明:Next.js 并未真正执行静态生成(SSG),而是退化为客户端渲染(CSR)。根本原因在于 _app.js 中的条件渲染逻辑破坏了服务端渲染流程。
? 问题定位:_app.js 中的致命判断
原始代码中这一行是症结所在:
return (
typeof window !== "undefined" && ( // ❌ 服务端 `window` 为 undefined → 返回 false → 渲染空内容
<>
>
)
);在服务端渲染(SSR)或静态生成(SSG)阶段,Node.js 环境下 typeof window === "undefined" 恒为 true,因此整个 JSX 表达式求值为 false,导致服务端返回空响应(无 HTML 内容)。浏览器端 JS 加载后才执行渲染,这就是“源码为空、禁 JS 不显示”的直接原因。
✅ 正确解法:移除服务端阻断逻辑
修改后的 _app.js 必须确保服务端和客户端均能正常渲染组件树:
import React from "react";
import App from "next/app";
import TagManager from "react-gtm-module";
import NextNProgress from "../components/NextNProgress";
import "bootstrap/dist/css/bootstrap.css";
import "../scss/index.scss";
const tagManagerArgs = {
gtmId: "########",
};
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
}
componentDidMount() {
TagManager.initialize(tagManagerArgs);
}
render() {
const { Component, pageProps } = this.props;
return (
<>
{/* 进度条组件需支持 SSR,建议检查其内部是否含 window/document 依赖 */}
>
);
}
}
export default MyApp;✅ 关键改动:
- 彻底移除 typeof window !== "undefined" 条件包裹,保证服务端可渲染完整 DOM 树;
- 保留 componentDidMount 中的 GTM 初始化(仅在客户端执行,安全);
- NextNProgress 组件需确认其 SSR 兼容性(避免在服务端调用 window 或 document)。
? 验证是否真正 SSG 成功
-
构建并预览静态产物:
next build && next export # 若使用 `next export` # 或直接运行:next build && next start
-
检查输出 HTML:
Shopxp购物系统Html版下载一个经过完善设计的经典网上购物系统,适用于各种服务器环境的高效网上购物系统解决方案,shopxp购物系统Html版是我们首次推出的免费购物系统源码,完整可用。我们的系统是免费的不需要购买,该系统经过全面测试完整可用,如果碰到问题,先检查一下本地的配置或到官方网站提交问题求助。 网站管理地址:http://你的网址/admin/login.asp 用户名:admin 密 码:admin 提示:如果您
- 访问 http://localhost:3000 → 右键「查看网页源代码」→ 应看到完整的、包含实际内容的 HTML(非仅 );
- 在 Chrome DevTools 的 Network 选项卡中,刷新页面,查看 index.html 响应体,确认内含预渲染的文本、标题、结构化数据等。
禁用 JavaScript 测试:
- Chrome 设置 → Privacy and Security → Site Settings → Content → JavaScript → Block;
- 重启页面 → 页面仍应完整显示(证明服务端已生成 HTML)。
⚠️ 注意事项与增强建议
-
安全性:若该组件内部依赖 window.addEventListener 或 document.querySelector,需改造为仅在客户端挂载: // 推荐写法:延迟客户端组件挂载 import { useEffect, useState } from 'react'; export default function SafeNProgress() { const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); return mounted ?: null; } -
_document.js 优化:你当前的 _document.js 是标准写法,但注意:
- 的 crossOrigin="anomynous" 拼写错误,应为 "anonymous";
- 所有 和 标签必须放在 内,你已正确实现。
-
SEO 强化补充(推荐): 在页面组件中使用 next/head 注入动态 meta:
import Head from 'next/head'; export default function ProductPage({ product }) { return ( <>{product.name} | DMI Store > ); }{product.name}
{product.description}
✅ 总结
Next.js 的 SSG 能力高度依赖服务端可执行的纯 React 渲染流程。任何在 _app.js 或页面中对 window 的同步依赖、条件屏蔽,都会导致静态 HTML 生成失败。修复核心永远是:确保服务端能产出完整 HTML 字符串,客户端仅负责增强交互。按本文方案调整后,你的产品页将真正具备搜索引擎可抓取、无障碍可访问、JS 禁用仍可用的生产级 SEO 表现。
- 访问 http://localhost:3000 → 右键「查看网页源代码」→ 应看到完整的、包含实际内容的 HTML(非仅







