FlexLayout icon indicating copy to clipboard operation
FlexLayout copied to clipboard

"ReferenceError: document is not defined" in server-side rendering

Open SillyFreak opened this issue 6 years ago • 2 comments

Server-side rendering gets me the following exception at import time:

ReferenceError: document is not defined
    at new DragDrop (.../node_modules/flexlayout-react/src/DragDrop.ts:40:23)
    at .../node_modules/flexlayout-react/src/DragDrop.ts:4:23
    at Object.<anonymous> (.../node_modules/flexlayout-react/src/DragDrop.ts:3:1)
    ...

DragDrop has a default instance, which tries to create a div at construction time, which fails on the server. Unfortunately, this fails at construction time so it can only be fixed by conditional importing of the module, and not rendering on the server. Preferably of course, rendering would work on the server; drag & drop is not needed there.

I'm using the React Starter Kit, which provides server-side rendering.

SillyFreak avatar Dec 23 '18 16:12 SillyFreak

We are having the same issue and we would very much appreciate it if someone can look into fixing it as this layout has such great potential but is failing when server side rendering. The error is coming from the DragDrop.js: DragDrop.instance = new DragDrop(); So far the only way we can go around it is to change this file and that we really don't want to do:

var canUseDOM = !!(
  (typeof window !== 'undefined' &&
  window.document && window.document.createElement)
);	
DragDrop.instance = canUseDOM ? new DragDrop() : null;

Thanks in advance to whoever fixes it :)

msimonian77 avatar Mar 26 '19 17:03 msimonian77

It looks like such a workaround maybe have already been applied here? https://github.com/caplin/FlexLayout/blob/989112f98d37047f7e74011376e7812a081ce9e9/src/DragDrop.ts#L5

However, is this library really going to work for SSR at all? I was looking at the main render method here:

https://github.com/caplin/FlexLayout/blob/989112f98d37047f7e74011376e7812a081ce9e9/src/view/Layout.tsx#L456

It says it uses the first render to do some measurement (which sounds unlikely to work in SSR), and only renders the layout on subsequent renders. Since componentDidMount and componentDidUpdate don't run on SSR, I don't see how this can possibly render properly. I'd love to be wrong about this, as the reason I'm interested in this library is the possibility of rendering nice-looking tab layouts on the server.

thomasjm avatar May 11 '23 08:05 thomasjm