Next.js 静态生成页面源码不可见问题的完整解决方案

6次阅读

Next.js 静态生成页面源码不可见问题的完整解决方案

本文详解 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 成功

  1. 构建并预览静态产物

    next build && next export  # 若使用 `next export` # 或直接运行:next build && next start
  2. 检查输出 HTML

    • 访问 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 表现。

text=ZqhQzanResources