在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
相关产品推荐
相关产品推荐

