samdenty / console-feed

Captures console.log's into a React Component 🔥
https://stackblitz.com/~/github.com/samdenty/console-feed
MIT License
662 stars 110 forks source link

"ReferenceError: document is not defined" when importing anything from 'console-feed' #99

Open crebro opened 2 years ago

crebro commented 2 years ago

image

I am currently working on an application that needs to get the console feed of an iframe although I don't think the application has anything to do with the error because it shows up just when I import anything without using it at all.

The following is the code that I am using in my application.

import React from 'react';
import { useEffect, useRef } from 'react/cjs/react.development';
import { Hook } from "console-feed/lib/Hook"
import { Unhook } from "console-feed/lib/Unhook"

function ProjectPreview({ preview_location, debouncedContent, onIframeLog }) {
  const iframeRef = useRef();

 useEffect(() => {
    Hook(
      iframeRef.current.contentWindow.console,
      (log) => onIframeLog(log),
      false
    )
    return () => Unhook(iframeRef.current.contentWindow.console)
  }, []) 

  useEffect(() => {
    iframeRef.current.src = 'about:blank';
    setTimeout(() => {
      iframeRef.current.src = preview_location;
    }, 10);
  }, [debouncedContent])

  return <div className='w-full h-full pt-5 px-4'>
      <div className='flex items-center text-white'>
        <div className='text-xs font-poppins'> Development Preview: </div> &nbsp;
        <div className='text-xs px-2 py-2 bg-[#C4C4C4] font-bold text-black'> {preview_location} </div>
      </div>
    <iframe ref={iframeRef} src={preview_location} className='w-full h-full my-2 mb-10 bg-white' />
  </div>;
}

export default ProjectPreview;
d-ivashchuk commented 2 years ago

you are probably using it in the framework where the window or document do not exist initially, like Next.js.

I am curios what would be the reasonable way of making it work there, as I also struggled with it now :/ @samdenty maybe you have an idea knowing the library internals

louis-cf-lin commented 2 years ago

I'm also encountering this error and using Next.js (as @d-ivashchuk suspected).

My workaround is to declare the functions outside the component and then dynamically import the package in a useEffect, something like this

let Hook
let Unhook

// some code ...

useEffect(() => {
  (async () => {
    ({ Console, Hook, Unhook } = await import("console-feed"));
    Hook(iframeRef.current.contentWindow.console, (log) => ((state) => [...state, log]), false);
  })();
  const dynRef = iframeRef.current;
  return () => Unhook(iframeRef.current.contentWindow.console)
}, []);

Doesn't fix the underlying problem but works fine until the issue is fixed