filestack / filestack-react

Official React component for Filestack - API and content management system that makes it easy to add powerful file uploading and transformation capabilities to any web or mobile application.
https://www.filestack.com
MIT License
164 stars 40 forks source link

window is not defined #65

Closed ksntcrq closed 5 years ago

ksntcrq commented 5 years ago

Hey,

When using server-side rendering, and import ReactFilestack from 'filestack-react';, I run into the following problem:

ReferenceError: window is not defined
    at Object. (/data/www/studocu/node_modules/filestack-react/dist/webpack:/webpack/universalModuleDefinition:8:1)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Module._compile (/data/www/studocu/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Object.newLoader [as .js] (/data/www/studocu/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Function._load (/usr/local/share/.config/yarn/global/node_modules/@pm2/io/src/metrics/httpMetrics.ts:190:35)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object. (/data/www/studocu/resources/assets/redux/studocu/components/DropArea.jsx:7:1)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Module._compile (/data/www/studocu/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Object.newLoader [as .jsx] (/data/www/studocu/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Function._load (/usr/local/share/.config/yarn/global/node_modules/@pm2/io/src/metrics/httpMetrics.ts:190:35)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object. (/data/www/studocu/resources/assets/redux/studocu/components/lists/DropAreaList.jsx:8:1)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Module._compile (/data/www/studocu/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Object.newLoader [as .jsx] (/data/www/studocu/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Function._load (/usr/local/share/.config/yarn/global/node_modules/@pm2/io/src/metrics/httpMetrics.ts:190:35)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object. (/data/www/studocu/resources/assets/redux/studocu/pages/Upload.jsx:33:1)
    at Module._compile (internal/modules/cjs/loader.js:759:30)
    at Module._compile (/data/www/studocu/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:770:10)
    at Object.newLoader [as .jsx] (/data/www/studocu/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:628:32)
    at Function.Module._load (internal/modules/cjs/loader.js:555:12)
    at Function._load (/usr/local/share/.config/yarn/global/node_modules/@pm2/io/src/metrics/httpMetrics.ts:190:35)
    at Module.require (internal/modules/cjs/loader.js:666:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at handleRender (/data/www/studocu/server.js:202:20)
    at Layer.handle [as handle_request] (/data/www/studocu/node_modules/express/lib/router/layer.js:95:5)
    at next (/data/www/studocu/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/data/www/studocu/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/data/www/studocu/node_modules/express/lib/router/layer.js:95:5)
    at /data/www/studocu/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/data/www/studocu/node_modules/express/lib/router/index.js:335:12)
    at next (/data/www/studocu/node_modules/express/lib/router/index.js:275:10)
    at /data/www/studocu/node_modules/body-parser/lib/read.js:130:5
    at invokeCallback (/data/www/studocu/node_modules/raw-body/index.js:224:16)
    at done (/data/www/studocu/node_modules/raw-body/index.js:213:7)
    at IncomingMessage.onEnd (/data/www/studocu/node_modules/raw-body/index.js:273:7)
    at IncomingMessage.emit (events.js:201:15)
    at IncomingMessage.EventEmitter.emit (domain.js:471:20)
    at endReadableNT (_stream_readable.js:1130:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:9)

So I have to conditionally import the component, which is not really convenient:

let ReactFilestack;
if (typeof window !== 'undefined' && window !== null) {
    ReactFilestack = require('filestack-react').default;
}

Because of that I also have a mismatch between server and client sides, as the button is not rendered on the server side but is on the client side.

The filestack-react version I use is 2.0.6.

AndrzejSala commented 5 years ago

@killiansc

I do not know what exactly limit the SSR has in comparison to CSR in terms of app rendering, but it seems that at the present moment it is not possible to render the whole running component on server side.

filestack-react is not a typical component, in the sense that it does not contain any DOM (except button or link) or own event handlers. It's more a layer of abstraction on filestack-js. It just calls methods from filestack-js sdk which dynamically load some scripts to build filestack-picker app and probably this scripts are not able to be rendered on server side.

You can check some workarounds for similar issue, people try to use ‘dynamic imports’ for it in this case. https://github.com/filestack/filestack-react/issues/57

ksntcrq commented 5 years ago

@AndrzejSala alright thanks, so for future reference, here is the solution I decided to implement:

import loadable from '@loadable/component';
const ReactFilestack = loadable(() => import('filestack-react'), { ssr: false });

We were already using loadable components, so I took advantage of it.

hichana commented 3 years ago

Also works to simply use the library included with Next.js. Example:

Importing into a parent component:

import dynamic from "next/dynamic"

const Picker = dynamic(() => import("../components/Picker"), { ssr: false })

Child component:

import ReactFilestack from 'filestack-react';

const Picker = () => (
<ReactFilestack
  apikey={YOUR_API_KEY}
  onSuccess={(res) => console.log(res)}
/>
)

export default Picker