Next.js预渲染/write页面出现ReferenceError: document is not defined求助
Next.js 13.4.19 预渲染/write页面时出现
document is not defined错误 报错信息
ReferenceError: document is not defined
at Object.(/vercel/path0/.next/server/chunks/34.js:10601:12)
额外信息
- Next.js版本:13.4.19
- 项目仓库:blogvarse
./write/page.jsx 代码
"use client"; import Image from "next/image"; import styles from "./writePage.module.css"; import { useEffect, useState } from "react"; import "react-quill/dist/quill.bubble.css"; import { useRouter } from "next/navigation"; import { useSession } from "next-auth/react"; import { getStorage, ref, uploadBytesResumable, getDownloadURL, } from "firebase/storage"; import { app } from "@/utils/firebase"; import ReactQuill from "react-quill"; const WritePage = () => { const { status } = useSession(); const router = useRouter(); const [open, setOpen] = useState(false); const [file, setFile] = useState(null); const [media, setMedia] = useState(""); const [value, setValue] = useState(""); const [title, setTitle] = useState(""); const [catSlug, setCatSlug] = useState(""); useEffect(() => { const storage = getStorage(app); const upload = () => { const name = new Date().getTime() + file.name; const storageRef = ref(storage, name); const uploadTask = uploadBytesResumable(storageRef, file); uploadTask.on( "state_changed", (snapshot) => { const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; console.log("Upload is " + progress + "% done"); switch (snapshot.state) { case "paused": console.log("Upload is paused"); break; case "running": console.log("Upload is running"); break; } }, (error) => {}, () => { getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => { setMedia(downloadURL); }); } ); }; file && upload(); }, [file]); if (status === "loading") { return <div className={styles.loading}>Loading...</div>; } if (status === "unauthenticated") { router.push("/"); } const slugify = (str) => str .toLowerCase() .trim() .replace(/[^\w\s-]/g, "") .replace(/[\s_-]+/g, "-") .replace(/^-+|-+$/g, ""); const handleSubmit = async () => { const res = await fetch("/api/posts", { method: "POST", body: JSON.stringify({ title, desc: value, img: media, slug: slugify(title), catSlug: catSlug || "style", }), }); if (res.status === 200) { const data = await res.json(); router.push(`/posts/${data.slug}`); } }; return ( <div className={styles.container}> <input type="text" placeholder="Title" className={styles.input} onChange={(e) => setTitle(e.target.value)} /> <select className={styles.select} onChange={(e) => setCatSlug(e.target.value)}> <option value="style">style</option> <option value="fashion">fashion</option> <option value="food">food</option> <option value="culture">culture</option> <option value="travel">travel</option> <option value="coding">coding</option> </select> <div className={styles.editor}> <button className={styles.button} onClick={() => setOpen(!open)}> <Image src="/plus.png" alt="" width={16} height={16} /> </button> {open && ( <div className={styles.add}> <input type="file" id="image" onChange={(e) => setFile(e.target.files[0])} style={{ display: "none" }} /> <button className={styles.addButton}> <label htmlFor="image"> <Image src="/image.png" alt="" width={16} height={16} /> </label> </button> <button className={styles.addButton}> <Image src="/external.png" alt="" width={16} height={16} /> </button> <button className={styles.addButton}> <Image src="/video.png" alt="" width={16} height={16} /> </button> </div> )} <ReactQuill className={styles.textArea} theme="bubble" value={value} onChange={setValue} placeholder="Tell your story..." /> </div> <button className={styles.publish} onClick={handleSubmit}> Publish </button> </div> ); }; export default WritePage;
已尝试的解决方法
- 排查代码中是否存在预渲染阶段服务器端访问DOM元素(如
document)的情况 - 查阅Next.js社区中该错误的常见原因并尝试多种解决方案
预期效果
/write页面能够成功预渲染且无报错,在服务器端和客户端均能正常加载运行
内容的提问来源于stack exchange,提问作者Muhammad Kaif Nazeer
相关产品推荐
相关产品推荐

