I'm building an open-source blogging platform with Next.js and encountering a frustrating error during deployment. When trying to prerender the /write page, I receive the following error:
ReferenceError: document is not defined
at Object.<anonymous> (/vercel/path0/.next/server/chunks/34.js:10601:12)
I've tried various solutions like checking for DOM access in server-side code and wrapping such code with conditional statements, but the error persists.
Additional Information:
Next.js version: 13.4.19 Project repository: https://github.com/MuhammadKaifNazeer/blogvarse/tree/main
Here is the code of ./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;
What I tried:
- DOM Access Checks: I carefully reviewed my code for any attempts to access DOM elements (like document) on the server side during prerendering.
- I researched common causes of "ReferenceError: document is not defined" errors in Next.js projects and explored various community-suggested solutions
What I expected:
I anticipated a successful prerendering of the /write page without any errors. I expected the page to load correctly and function as intended, both on the server and client side.
Problem :
Possible Cause :
Solution :
Try changing :
to
Please Read :