Next.js Discord

Discord Forum

ReferenceError: document is not defined

Answered
Thai posted this in #help-forum
Open in Discord
ThaiOP
Hey everyone!

I am having trouble building my project. I have two dependencies that need access to document directly. The section causing the problem is in the useEffect.

'use client';
import React, { useEffect, useRef, useState } from 'react';
import Quill from 'quill';
import Delta from 'quill-delta';
import "./styles.css";
import QuillAudioEmbed from 'quill-audio-embed';
import { modules as defaultModules } from '../../constants/quill';

type QuillProps = {
  theme?: string,
  modules?: Record<string, unknown>,
  value: Delta,
  readOnly?: boolean,
  onTextChange?: (delta: Delta, oldContents: Delta, source: string, editor: Quill) => void,
  onReady?: (editor: Quill) => void
}

function ReactQuill(props: QuillProps) {
  const {
    theme,
    modules,
    value,
    readOnly,
    onTextChange,
    onReady
  } = props;

  const [editor, setEditor] = useState<Quill>();
  const [ready, setReady] = useState<boolean>(false);
  const quillContainer = useRef<any>();

  useEffect(() => {
    if (ready) return;

    // These access the document
    QuillAudioEmbed.setQuillConstructor(Quill);
    Quill.register('modules/audioEmbed', QuillAudioEmbed);

    const ed = new Quill(quillContainer.current, {
      modules: modules ?? defaultModules,
      theme: theme ?? 'snow',
      readOnly: !!readOnly,
    });

    ed.setContents(value);

    if (onTextChange) {
      ed.on('text-change', (d, od, s) => onTextChange(d, od, s, ed));
    }

    setEditor(ed);
    setReady(true);
       
    return () => {
      ed.off('text-change');
    }
  }, []);

  useEffect(() => {
    if (ready && onReady && editor) {
      onReady(editor);
    }

  }, [ready, editor])

  return (
    <div ref={quillContainer} id="quill-editor"></div>
  )
}

export default ReactQuill;
Answered by B33fb0n3
load your component [without ssr](https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading#skipping-ssr). You can do it like that:
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
View full answer

3 Replies

@Thai Hey everyone! I am having trouble building my project. I have two dependencies that need access to `document` directly. The section causing the problem is in the useEffect. typescript 'use client'; import React, { useEffect, useRef, useState } from 'react'; import Quill from 'quill'; import Delta from 'quill-delta'; import "./styles.css"; import QuillAudioEmbed from 'quill-audio-embed'; import { modules as defaultModules } from '../../constants/quill'; type QuillProps = { theme?: string, modules?: Record<string, unknown>, value: Delta, readOnly?: boolean, onTextChange?: (delta: Delta, oldContents: Delta, source: string, editor: Quill) => void, onReady?: (editor: Quill) => void } function ReactQuill(props: QuillProps) { const { theme, modules, value, readOnly, onTextChange, onReady } = props; const [editor, setEditor] = useState<Quill>(); const [ready, setReady] = useState<boolean>(false); const quillContainer = useRef<any>(); useEffect(() => { if (ready) return; // These access the document QuillAudioEmbed.setQuillConstructor(Quill); Quill.register('modules/audioEmbed', QuillAudioEmbed); const ed = new Quill(quillContainer.current, { modules: modules ?? defaultModules, theme: theme ?? 'snow', readOnly: !!readOnly, }); ed.setContents(value); if (onTextChange) { ed.on('text-change', (d, od, s) => onTextChange(d, od, s, ed)); } setEditor(ed); setReady(true); return () => { ed.off('text-change'); } }, []); useEffect(() => { if (ready && onReady && editor) { onReady(editor); } }, [ready, editor]) return ( <div ref={quillContainer} id="quill-editor"></div> ) } export default ReactQuill;
load your component [without ssr](https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading#skipping-ssr). You can do it like that:
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
Answer
ThaiOP
@B33fb0n3 heyy thanks a lot man, been wrestling with this for a few months!