ngx-quill: Angular Universal Break

Hi, I’m using this library in my Angular Universal App, however once I add it, it breack the server after running my server it immediately stops with the following error:

/node_modules/quill/dist/quill.js:7450
var elem = document.createElement('div');
           ^

ReferenceError: document is not defined

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 107 (51 by maintainers)

Most upvoted comments

You could work around this by creating an empty mock of ngx-quill module - and during compilation replace the the real module with the empty mock for the server build.

ngx-quill empty mock could be:

import { Component, NgModule, Input, Output, EventEmitter } from '@angular/core';

export interface CustomOption {
    import: string;
    whitelist: Array<any>;
}

@Component({
    selector: 'quill-editor',
    template: ''
})
export class QuillEditorComponent {
    @Input() theme: string;
    @Input() modules: { [index: string]: Object };
    @Input() readOnly: boolean;
    @Input() placeholder: string;
    @Input() maxLength: number;
    @Input() minLength: number;
    @Input() required: boolean;
    @Input() formats: string[];
    @Input() style: any = {};
    @Input() strict: boolean = true;
    @Input() scrollingContainer: HTMLElement | string;
    @Input() bounds: HTMLElement | string;
    @Input() customOptions: CustomOption[] = [];

    @Output() onEditorCreated: EventEmitter<any> = new EventEmitter();
    @Output() onContentChanged: EventEmitter<any> = new EventEmitter();
    @Output() onSelectionChanged: EventEmitter<any> = new EventEmitter();
}

@NgModule({
    declarations: [
        QuillEditorComponent
    ],
    exports: [
        QuillEditorComponent
    ]
})

export class QuillModule {
}

I use Webpack - and during my server build, I replace the real module with the mock using NormalModeReplaceMentPlugin. I have a separate config for the server build:

const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');

/**
 * This is a server config which is merged on top of common config
 */

module.exports = {
    ...bla bla other stuff...

    plugins: [
        new NormalModuleReplacementPlugin(
            /quill/,
           root('./Client/app/shared/servermocks/quillmodule.mock.ts')
          )
    ]
};

It works well - and I’ve done it with a few other libraries too.

There is even an example Link in the readme to a Universal project + live Demo.

Tom Müller notifications@github.com schrieb am Mi., 5. Aug. 2020, 20:20:

I am running an Angular 9 app which I just added universal support for. The build still breaks because of this error. I upgraded to ngx-quill 12 and still receive this error. I read the whole thread, but I am still confused about the solution. What do I need to do to use ngx-quill with Angular Universal in Angular 9? Thanks for clarification!

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/KillerCodeMonkey/ngx-quill/issues/91#issuecomment-669357959, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARI4YEEUNXH3UK3DNYJK33R7GPHPANCNFSM4EKN4ZHA .

@KillerCodeMonkey While you’re right it is a problem with image-resize, it also is a problem with several other plugins. quill-image-resize-module has been forked so many times, and non of the changes seem to work well. Anyway, I went back to the nifty webpack, as I found messing with the globals creates new different errors in one of my other projects. So, I had to replace just the quill-image-resize plugin instead of quill in general, since you fixed that. (see my above webpack implementation for reference)

custom-webpack.config.js

const webpack = require('webpack');
const path = require('path');

module.exports = {
    plugins: [
        new webpack.NormalModuleReplacementPlugin(/^quill-image-resize$/, path.join(__dirname, './src/app/mocks/quill.mock.server.ts'))
    ]
};

quill.mock.server.ts

export default class ImageResize {
    constructor() {}
}

See Updated Repository

@KillerCodeMonkey Could you add styles to the Quill.forRoot() declaration so that I don’t have to keep defining it in my code like so:

<quill-editor [styles]="{ resize: 'vertical', 'overflow-y': 'auto' }"></quill-editor>

Thanks!

GOT IT WORKING!!! Apparently there is a difference between quill-image-resize-module and quill-image-resize, at least in the way you import them. Perhaps somebody smarter than me with classes can explain how to get the other one working as well. Either way, what works, works. Here is my find code:

import { Component, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

let Quill: any = null;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  title = 'ngxQuillSSR';

  editor_modules = {};

  constructor(
    @Inject(PLATFORM_ID) protected platformId: any
  ) {
    if (isPlatformBrowser(this.platformId)) {
      Quill = require('quill');
      const ImageResize = require('quill-image-resize').default;
      const { ImageDrop } = require('quill-image-drop-module');
      Quill.register('modules/imageResize', ImageResize);
      Quill.register('modules/imageDrop', ImageDrop);
    }
    this.editor_modules = {
      toolbar: {
        container: [
          [{ 'font': [] }],
          [{ 'size': ['small', false, 'large', 'huge'] }],
          ['bold', 'italic', 'underline', 'strike'],
          [{ 'header': 1 }, { 'header': 2 }],
          [{ 'color': [] }, { 'background': [] }],
          [{ 'list': 'ordered' }, { 'list': 'bullet' }],
          [{ 'align': [] }],
          ['link', 'image']
        ]
      },
      imageResize: true,
      imageDrop: true
    };
  }
}

And I will try and keep my repository updated unless @KillerCodeMonkey decides to add his own version. I failed in every way possible, but it works. 😃

as my experiences ngx-quill is working in general. so if you are using plain ngx-quill without any module or additional imports. ssr should work… isn’t it?

@KillerCodeMonkey Yes, SSR works if you are not importing modules like ImageResize… Plain ngx-quill works on SSR