react-quill icon indicating copy to clipboard operation
react-quill copied to clipboard

ReferenceError: document is not defined with Next v13

Open nalnir opened this issue 1 year ago • 9 comments

Followed the demo example provided in the repo, tried with isWindowLoaded after setting it true in componentDidMount, but the same error persists.

nalnir avatar Sep 27 '23 08:09 nalnir

the same issue on my side

wolfag avatar Sep 30 '23 04:09 wolfag

In editor.tsx component

'use client';

import ReactQuill from 'react-quill';
import * as React from 'react';
import { forwardRef } from 'react';
import { twMerge } from 'tailwind-merge';
import 'react-quill/dist/quill.snow.css';

export const Editor = forwardRef<
  React.ElementRef<typeof ReactQuill>,
  React.ComponentPropsWithoutRef<typeof ReactQuill>
>(({ className, ...props }, forwardedRef) => (
  <ReactQuill
    className={twMerge(className)}
    ref={forwardedRef}
    theme="snow"
    {...props}
  />
));

Editor.displayName = 'Editor';

In server component:

import { Editor } from '<path>/editor';

export default function ServerComponent(): React.JSX.Element {
  return (<Editor />)
}

thevuong avatar Oct 09 '23 05:10 thevuong

Hi! I'm getting the same issue.

Rednegniw avatar Oct 31 '23 08:10 Rednegniw

@thevuong it doesnot work

v-kryvenda avatar Nov 06 '23 13:11 v-kryvenda

It worked for me only replacing the default import with this one

// import ReactQuill from "react-quill";
import dynamic from "next/dynamic";

export const MyComponent = () => {
  const ReactQuill = useMemo(
      () => dynamic(() => import("react-quill"), { ssr: false }),
      []
  );
  
  return (
}

ImJoseHidalgo avatar Nov 11 '23 05:11 ImJoseHidalgo

I found a solution for it.

The problem not only for your import the react-quill, sometimes it cause by the quill.register modules. It definitely call the document inside the function I think.

So, for me, I create another file to solve it dynamic(() => import("your editor path"), { ssr: false }) , and it works for me.

cjfff avatar Dec 07 '23 08:12 cjfff

It worked for me only replacing the default import with this one

// import ReactQuill from "react-quill";
import dynamic from "next/dynamic";

export const MyComponent = () => {
  const ReactQuill = useMemo(
      () => dynamic(() => import("react-quill"), { ssr: false }),
      []
  );
  
  return (
}

this worked for me on nextjs 14

sonangrai avatar Jan 10 '24 11:01 sonangrai

It worked for me only replacing the default import with this one

// import ReactQuill from "react-quill";
import dynamic from "next/dynamic";

export const MyComponent = () => {
  const ReactQuill = useMemo(
      () => dynamic(() => import("react-quill"), { ssr: false }),
      []
  );
  
  return (
}

this worked for me on nextjs 14

But if you have to register those built-in component, you'll import it in another file, then you'll incur the same issue.

So, I recommand you don't just make the react-quill as the ssr-false import but add the whole custom component also.

cjfff avatar Jan 10 '24 14:01 cjfff

Just work fine for me as well when replacing with dynamic import and ssr false in TextEditor.tsx

"use client";

import { ErrorMessage, useField } from "formik";
import React, { FC, useId, useState, forwardRef, useMemo } from "react";
import "react-quill/dist/quill.snow.css";
import ErrorC from "../Error/ErrorC";
import classNames from "classnames";
import dynamic from "next/dynamic";

interface TextEditorProps {
  name: string;
  placeholder: string;
  label?: string;
  labelClass?: string;
}

const TextEditor: FC<TextEditorProps> = ({
  name,
  placeholder,
  label,
  labelClass,
}) => {
  const ReactQuill = useMemo(
    () => dynamic(() => import("react-quill"), { ssr: false }),
    []
  );
  const [field, meta, helpers] = useField(name);
  const { setValue } = helpers;
  const { value } = field;
  const Id = useId();

  return (
    <section className="vstack gap-3 no-light position-relative">
      {typeof label !== "undefined" && (
        <label
          className={classNames(
            `form-label ${labelClass ? "" : "text-dark"} `,
            labelClass
          )}
          htmlFor={Id}
        >
          {label}
        </label>
      )}

      <section>
        <ReactQuill
          {...field}
          theme="snow"
          style={{
            color: "white !important",
          }}
          value={value}
          placeholder={placeholder}
          onChange={(content, delta, source, editor) => {
            setValue(content);
          }}
        />
        {meta.error && <ErrorC>{meta.error}</ErrorC>}
      </section>
    </section>
  );
};

export default TextEditor;

mrwilbroad avatar Jun 08 '24 12:06 mrwilbroad