Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document is not defined in Next Js 14 app router #1002

Open
sakir101 opened this issue Sep 9, 2024 · 1 comment
Open

Document is not defined in Next Js 14 app router #1002

sakir101 opened this issue Sep 9, 2024 · 1 comment

Comments

@sakir101
Copy link

sakir101 commented Sep 9, 2024

I used react quill in next 14 app router. When I build the client side it shows this type of error. I I don't understand why this is happening. In my code I made ssr: false

`"use client";

import { Button, Select, message } from "antd";
import { useEffect, useState } from "react";
import { InfoCircleOutlined } from "@ant-design/icons";
import "react-quill/dist/quill.snow.css";
import dynamic from "next/dynamic";
import "../../../../../components/QuillCss/page.css";
import { getUserInfo } from "@/services/auth.service";
import { useAssignRelatedWorksFacultyMutation } from "@/redux/api/relatedWorksFacultyApi";
import { formats, modules } from "@/components/ui/QuillModuleFormat";
import { useDebounced } from "@/redux/hooks";
import { useGetAssignExpertiseQuery } from "@/redux/api/facultyApi";

const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });
const RelatedWorkCreateFaculty = () => {
const query: Record<string, any> = {};
const [skillSelect, setSkillSelect] = useState(false);
const [english, setEnglish] = useState(true);
const [bangla, setBangla] = useState(false);
const [interests, setInterests] = useState("");
const [description, setDescription] = useState("");
const [isError, setError] = useState("");
const [isErrorOption, setErrorOption] = useState("");
const [searchTerm, setSearchTerm] = useState("");
const [size, setSize] = useState(100);

query["searchTerm"] = searchTerm;
query["size"] = size;
const debouncedTerm = useDebounced({
searchQuery: searchTerm,
delay: 600,
});

if (!!debouncedTerm) {
query["searchTerm"] = debouncedTerm;
}

const { userId } = getUserInfo() as any;

const { data } = useGetAssignExpertiseQuery(
{
id: userId,
arg: query,
},
{ refetchOnMountOrArgChange: true }
);

const interestData = data?.interest;

const interestOptions = interestData?.map((interest) => {
return {
label: interest?.title,
value: interest?.id,
};
});

const [assignRelatedWorksFaculty] = useAssignRelatedWorksFacultyMutation();

const onSelect = () => {
setSkillSelect(!skillSelect);
};

const selectLanguageEnglish = () => {
setEnglish(true);
setBangla(false);
};

const selectLanguageBangla = () => {
setBangla(true);
setEnglish(false);
};

const handleChange = (value: string) => {
setInterests(value);
};

const onSubmit = async () => {
if (interests === undefined || interests === "") {
setErrorOption("Set work field first");
return;
}

if (description.length < 100) {
  setError("Required, Add description minimum length 100 characters");
  return;
}

const key = "loadingKey";
message.loading({ content: "Loading...", key });

const data = {
  description,
};

try {
  assignRelatedWorksFaculty({ data, id: userId, interestId: interests })
    .unwrap()
    .then(() => {
      message.success("Work detail added successfully");
    })
    .catch((err) => {
      message.error("Failed to add work detail");
    })
    .finally(() => {
      message.destroy(key);
      setInterests("");
      setDescription("");
      setError("");
      setErrorOption("");
    });
} catch (error) {
  throw error;
}

};

return (



Add your expertise related work





{isErrorOption && {isErrorOption}} <div className="w-4/5 lg:w-1/2 my-3"> <div className="p-3 bg-slate-300 shadow-md shadow-slate-600 rounded-md form-group row w-full" style={{ margin: "15px 0px" }} > <label className="font-weight-bold"> {" "} Description <span className="required"> * </span>{" "} </label> <ReactQuill value={description} onChange={setDescription} modules={modules} formats={formats} placeholder={"Write Description..."} /> {isError && <p className="text-red-500">{isError}</p>} </div> </div> <div className="flex justify-center"> <button className="btn btn-primary" onClick={() => onSubmit()}> Submit </button> </div> </div> <div> <button className="border-none bg-transparent mx-5 text-lg font-semibold text-red-500 cursor-pointer hover:text-red-800" onClick={onSelect} > <InfoCircleOutlined /> About Interest Select </button> <div> {skillSelect ? ( <div className="my-5"> <div className="flex justify-center items-center text-center mx-auto"> <Button className="btn bg-blue-600 btn-sm text-white" onClick={selectLanguageEnglish} > English </Button> <Button className="btn bg-green-600 btn-sm text-white ms-4" onClick={selectLanguageBangla} > Bangla </Button> </div> {english ? ( <div className="my-4"> <p className="text-center text-lg font-medium"> Why you chose select </p> </div> ) : ( <div className="my-4"> <p className="text-center text-lg font-medium"> কেন তুমি তমার ইন্তেরেস্ত সিলেক্ট করবা </p> </div> )} </div> ) : ( <div></div> )} </div> </div> </div> ); }; export default RelatedWorkCreateFaculty; `
@goffxnca
Copy link

goffxnca commented Oct 16, 2024

I also ran into the same issue a few days ago on Next14 app router when working with ReactQuill. The error document is not defined typically happens because ReactQuill relies on the document object, which isn't available during SSR.

It looks like you’ve already used use client to mark the page as a client component, which is the right step. However, in some cases, this error can still occur if there’s any SSR attempt before the client-side rendering takes over.

The shortest working solution I found is to use a dynamic import with ssr: false, bc ReactQuill only runs on the client side. Here's the code:

"use client";
import React, { useState } from "react";
import "react-quill/dist/quill.snow.css";
import dynamic from "next/dynamic";
const ReactQuill = dynamic(() => import("react-quill"), { ssr: false });

export default function Home() {
  const [value, setValue] = useState("");
  return (
    <div>
      <ReactQuill theme="snow" value={value} onChange={setValue} />
      {value}
    </div>
  );
}

I put together a CodeSandbox if you’d like to check it out live. Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants