You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Vercel部署NextJS 14前端时遭遇ReferenceError问题求助

Next.js 14部署Vercel时预渲染阶段document is not defined错误解决方案

错误背景

使用Next.js 14.2.8(app目录结构)在Vercel部署网站时,构建阶段预渲染过程中触发ReferenceError: document is not defined错误,且所有出错页面的代码中未直接使用document对象。

错误日志

ReferenceError: document is not defined
    at createTag (/vercel/path0/.next/server/chunks/9869.js:151:25622)
    at /vercel/path0/.next/server/chunks/9869.js:151:38510
    at /vercel/path0/.next/server/chunks/9869.js:151:38633
    at /vercel/path0/.next/server/chunks/9869.js:151:41458
    at /vercel/path0/.next/server/chunks/9869.js:151:25287
    at 60496 (/vercel/path0/.next/server/chunks/9869.js:151:25291)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:143)
    at 88924 (/vercel/path0/.next/server/chunks/9869.js:152:58908)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:143)
    at 85912 (/vercel/path0/.next/server/chunks/5708.js:34:11987)
   Generating static pages (13/18) 
ReferenceError: document is not defined
    at createTag (/vercel/path0/.next/server/chunks/9869.js:151:25622)
    at /vercel/path0/.next/server/chunks/9869.js:151:38510
    at /vercel/path0/.next/server/chunks/9869.js:151:38633
    at /vercel/path0/.next/server/chunks/9869.js:151:41458
    at /vercel/path0/.next/server/chunks/9869.js:151:25287
    at 60496 (/vercel/path0/.next/server/chunks/9869.js:151:25291)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:143)
    at 88924 (/vercel/path0/.next/server/chunks/9869.js:152:58908)
    at t (/vercel/path0/.next/server/webpack-runtime.js:1:143)
    at 85912 (/vercel/path0/.next/server/chunks/5708.js:34:11987) {
  digest: '2326889752'
}

受影响页面路径

Export encountered errors on following paths:
    /Contact/page: /Contact
    /_not-found/page: /_not-found
    /admin/UnasssignedByWorker/page: /admin/UnasssignedByWorker
    /admin/reports/page: /admin/reports
    /admin/verify_worker/page: /admin/verify_worker
    /login/page: /login
    /page: /
    /register/page: /register
    /user/User_Profile/page: /user/User_Profile
    /user/create_request/page: /user/create_request
    /user/hire/page: /user/hire
    /user/view_request/page: /user/view_request
    /worker/all_request/page: /worker/all_request
    /worker/hire/page: /worker/hire
    /worker/requests/page: /worker/requests

错误原因分析

错误核心是服务端预渲染时访问了仅存在于浏览器环境的document对象。虽然页面代码未直接调用document,但依赖的第三方库(如react-hot-toast、react-icons)或自定义组件(如Footer)在初始化阶段可能直接操作了DOM,而Next.js默认对app目录页面执行服务端渲染(SSR)或静态生成(SSG),服务端环境不存在document,因此触发报错。

解决方案

1. 兼容第三方库的服务端渲染

以react-hot-toast为例,其Toaster组件默认初始化时会操作DOM,需通过动态导入禁用服务端渲染:

import dynamic from 'next/dynamic';
const Toaster = dynamic(() => import('react-hot-toast').then(mod => mod.Toaster), { ssr: false });

2. 修复自定义组件的浏览器API依赖

如果Footer等自定义组件中使用了document或浏览器专属API,同样需用动态导入禁用服务端渲染:

const Footer = dynamic(() => import('../_components/Footer'), { ssr: false });

3. 全局强制客户端渲染

对于无需预渲染的页面,可在组件顶部添加配置,强制客户端渲染:

export const dynamic = 'force-dynamic';

4. 更新依赖版本

检查react-hot-toast、react-icons等依赖是否为最新版本,旧版本可能存在服务端渲染兼容性问题。

修正后的示例页面代码(Contact页面)

"use client";
import React, { useState } from "react";
import { FaGithub, FaEnvelope, FaLinkedin } from "react-icons/fa";
import { toast } from "react-hot-toast";
import dynamic from 'next/dynamic';
import Image from "next/image";

// 动态导入Toaster,禁用服务端渲染
const Toaster = dynamic(() => import('react-hot-toast').then(mod => mod.Toaster), { ssr: false });
// 动态导入Footer,禁用服务端渲染
const Footer = dynamic(() => import("../_components/Footer"), { ssr: false });

const ContactForm = () => {
  const [Name, SetName] = useState("");
  const [Email, SetEmail] = useState("");
  const [Message, SetMessage] = useState("");
  const [loading, Setloading] = useState(false);

  async function handleSubmit(e) {
    e.preventDefault();
    try {
      Setloading(true);
      const response = await fetch(
        "https://ayushreactbackend.onrender.com/api/v1/auth/SubmitUserQueryForm",
        {
          method: "POST",
          headers: {
            "Content-type": "application/json",
          },
          body: JSON.stringify({ Name, Email, Message }),
        }
      );
      if (response.status === 200) {
        toast.success("We received your query");
        SetName("");
        SetEmail("");
        SetMessage("");
      } else {
        toast.error("Please try after some time");
      }
    } catch (error) {
      toast.error("Something went wrong");
    } finally {
      Setloading(false);
    }
  }

  return (
    <div className="w-full max-w-md">
      {" "}
      <h1 className="text-4xl font-bold text-gray-800 mt-8 text-center">
        Get in Touch
      </h1>
      <p className="text-gray-600 text-lg mb-6 text-center">
        We are here for you. How can we help?
      </p>
      <form onSubmit={handleSubmit} className=" rounded-lg p-6 w-full max-w-md">
        <div className="mb-4">
          <label htmlFor="name" className="block text-gray-700 font-medium">
            Name
          </label>
          <input
            type="text"
            className="w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
            id="name"
            required
            placeholder="Enter your name"
            value={Name}
            onChange={(e) => SetName(e.target.value)}
          />
        </div>
        <div className="mb-4">
          <label htmlFor="email" className="block text-gray-700 font-medium">
            Email
          </label>
          <input
            type="email"
            className="w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
            id="email"
            required
            placeholder="Enter your email"
            value={Email}
            onChange={(e) => SetEmail(e.target.value)}
          />
        </div>
        <div className="mb-4">
          <label htmlFor="message" className="block text-gray-700 font-medium">
            Message
          </label>
          <textarea
            className="w-full p-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none "
            id="message"
            rows="4"
            required
            placeholder="Go ahead! We are listening..."
            value={Message}
            onChange={(e) => SetMessage(e.target.value)}
          ></textarea>
        </div>
        <button
          type="submit"
          className="w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 rounded-lg"
          disabled={loading}
        >
          {loading ? "Sending..." : "Submit"}
        </button>
      </form>
    </div>
  );
};

const Contact = () => {
  return (
    <>
      <div className="flex flex-col items-center w-full px-4 mt-8">
        <Toaster />
        <div className="flex flex-wrap justify-center gap-8 sm:w-3/4 p-3 bg-white shadow-lg mt-3">
          <ContactForm />
          <div className="flex flex-col p-3 rounded-lg">
            <Image
              src="/contacus.jpg"
              className="w-80 rounded-lg shadow-lg"
              alt="Contact Us"
              width={400}
              height={200}
            />
            <p className="text-xl font-semibold mt-4 mb-2 text-center">
              Contact us
            </p>
            <div className="flex flex-col gap-2">
              <a
                href="mailto:asharma7588@gmail.com"
                className=" text-lg flex items-center mt-2"
              >
                <FaEnvelope className="text-xl mr-2" /> asharma7588@gmail.com
              </a>

              <a
                href="mailto:Mohitsinghtadhiyal8@gmail.com"
                className=" text-lg flex items-center mt-2"
              >
                <FaEnvelope className="text-xl mr-2" />{" "}
                Mohitsinghtadhiyal8@gmail.com
              </a>

              <div className=" text-lg flex items-center mt-2">
                <a
                  href="https://www.linkedin.com/in/ayush-sharma-a155a8267"
                  target="blank"
                  className="flex"
                >
                  <FaLinkedin className="text-2xl mr-2" /> Ayush Sharma
                </a>
              </div>
            </div>
          </div>
        </div>

        {/* developed by  */}

        <p className="text-2xl font-bold text-gray-800 mt-10">Developed By</p>
        <div className="flex flex-col items-center mt-4">
          <Image
            src="/Ayush2.jpg"
            alt="Ayush Sharma"
            className="w-32 h-32 rounded-full object-cover shadow-lg mb-4"
            width={200}
            height={200}
          />
          <p className="text-lg font-semibold">Ayush Sharma</p>
          <p className="text-gray-600">Developer and Project Manager</p>
          <div className="flex mt-4 space-x-4">
            <a
              href="https://github.com/AyushSharma72"
              target="_blank"
              className="bg-gray-800 text-white p-3 rounded-full"
            >
              <FaGithub className="text-2xl" />
            </a>
            <a
              href="mailto:asharma7588@gmail.com"
              className="bg-red-500 text-white p-3 rounded-full"
            >
              <FaEnvelope className="text-2xl" />
            </a>
            <a
              href="https://www.linkedin.com/in/ayush-sharma-a155a8267"
              target="_blank"
              className="bg-blue-700 text-white p-3 rounded-full"
            >
              <FaLinkedin className="text-2xl" />
            </a>
          </div>
        </div>
      </div>
      <Footer />
    </>
  );
};

export default Contact;

内容的提问来源于stack exchange,提问作者Task Master

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 23:12:03