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

Server side rendering broken since Sep 20th commits #122

Closed
joewestcott opened this issue Sep 24, 2016 · 9 comments

Comments

@joewestcott
Copy link

commented Sep 24, 2016

/node_modules/quill/dist/quill.js:2245
var elem = document.createElement('div');
ReferenceError: document is not defined
@alexkrolick

This comment has been minimized.

Copy link
Collaborator

commented Sep 24, 2016

You'll probably want to file this issue upstream with Quill. The calls to document are in the core editor module.

https://github.com/quilljs/quill/search?utf8=%E2%9C%93&q=document.createElement

@zenoamaro

This comment has been minimized.

Copy link
Owner

commented Oct 19, 2016

@alexkrolick is correct, Quill is tightly coupled to the browser at the moment.

What could be done is to render only a <textarea> on server side. This should be easily accomplished in user code, but I guess we could see if it's possible to add some support here.

@zenoamaro zenoamaro closed this Feb 7, 2017

@calvintennant

This comment has been minimized.

Copy link

commented Feb 14, 2017

I was able to work around this limitation by instantiating react-quill only on the client. Note that import only works on the top level, so I use require.

I imagine the maintainers of this module should be able to prevent calls to the DOM when it's not available, without too much trouble. Big +1 for that change.

Here's my wrapper component to support isomorphic rendering:

import React, {Component} from 'react'

export default class FormHtmlEditor extends Component {
  constructor(props) {
    super(props)
    if (document) {
      this.quill = require('react-quill')
    }
  }

  render() {
    const Quill = this.quill
    if (Quill) {
      return (
        <Quill
          onChange={this.props.onChange}
          theme="bubble"
          value={this.props.value}
        />
      )
    } else {
      return null
    }
  }
}
@alexkrolick

This comment has been minimized.

Copy link
Collaborator

commented Feb 14, 2017

Yes, ES6 modules are static. You can still probably detect document in the render, though:

import React, {Component} from 'react'
import Quill from 'react-quill'

export default class FormHtmlEditor extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    if (document) {
      return (
        <Quill
          onChange={this.props.onChange}
          theme="bubble"
          value={this.props.value}
        />
      )
    } else {
      return <textarea value={this.props.value} />
    }
  }
}

Not sure if we want to add support to the module directly - seems a bit too automagicky to me at the moment.

@calvintennant

This comment has been minimized.

Copy link

commented Feb 14, 2017

All of my components are bundled up with WebPack and sent from the server using renderToString. When quill is included in the server side bundle via import my server crashes with the folowing output:

/path/to/src/node_modules/quill/dist/quill.js:2377
  var elem = document.createElement('div');
             ^

ReferenceError: document is not defined
    at Object.<anonymous> (/path/to/src/node_modules/quill/dist/quill.js:2377:13)
    at __webpack_require__ (/path/to/src/node_modules/quill/dist/quill.js:36:30)
    at Object.<anonymous> (/path/to/src/node_modules/quill/dist/quill.js:1669:2)
    at __webpack_require__ (/path/to/src/node_modules/quill/dist/quill.js:36:30)
    at Object.<anonymous> (/path/to/src/node_modules/quill/dist/quill.js:76:15)
    at __webpack_require__ (/path/to/src/node_modules/quill/dist/quill.js:36:30)
    at Object.defineProperty.value (/path/to/src/node_modules/quill/dist/quill.js:7798:14)
    at __webpack_require__ (/path/to/src/node_modules/quill/dist/quill.js:36:30)
    at Object.<anonymous> (/path/to/src/node_modules/quill/dist/quill.js:63:19)
    at __webpack_require__ (/path/to/src/node_modules/quill/dist/quill.js:36:30)

My hack as above using require was to work around this crash.

@aldidana

This comment has been minimized.

Copy link

commented May 17, 2017

this is how to check if it run in a browser or not (i changed a code from @calvintennant ):

import React, { Component } from 'react'

export default class FormHtmlEditor extends Component {
  constructor(props) {
    super(props)
    if (typeof window !== 'undefined') {
      this.ReactQuill = require('react-quill')
    }
  }

  render() {
    const ReactQuill = this.ReactQuill
    if (typeof window !== 'undefined' && ReactQuill) {
      return (
        <ReactQuill
          onChange={this.props.onChange}
          theme="bubble"
          value={this.props.value}
        />
      )
    } else {
      return <textarea />;
    }
  }
}
@jdmswong

This comment has been minimized.

Copy link

commented Sep 28, 2017

I used if (!__SERVER__) instead, looks cleaner

@yalamber

This comment has been minimized.

Copy link

commented Jun 18, 2019

I wrote this with dynamic module

import { Spin } from 'antd';
import dynamic from 'next/dynamic';

const QuillNoSSRWrapper = dynamic(
  import('react-quill')
  {
    ssr: false,
    loading: () => <Spin />,
  }
);

export default QuillNoSSRWrapper;
@alexlafroscia

This comment has been minimized.

Copy link

commented Jul 11, 2019

I really liked the solution that @yalamber came up with, using next/dynamic, but I want to have the "placeholder" render the content that would eventually be in the editor, so that it shows the content while the page is hydrating. Unfortunately you don't get access to the props that you pass to QuillNoSSRWrapper within the loading component 😦

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.