React JS Server side issue - window not found
Solution 1:
Here is a npm library which can handle window, document and global object for you: Global.
Then you can safely write:
import window from 'global'
const mySpecialWindowFunction = () => {
return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
};
Solution 2:
If you're doing server side rendering, there's a good chance that the global window object is going to be undefined because that is only something the client will understand.
Note: Initially, when you start up your project its going to render out a complete string of your DOM (at this point it will not know about
window
because it is server side, but then re-render with the client-side code to which your window object will be available!
There is a workaround that I am using in this case. This is what I have for my webpack plugin:
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDevelopment ? '"development"' : '"production"',
'process.env.BROWSER': JSON.stringify(true),
__DEV__: isDevelopment
}),
So I use process.env.BROWSER
to my advantage because it will be defined as undefined
if it is server side, and it will be true
if the client side is done rendering.
Since everything just stops working when there isn't a window object on the server side we can add this:
const mySpecialWindowFunction = () => {
/* START HACK */
if (!process.env.BROWSER) {
global.window = {}; // Temporarily define window for server-side
}
/* END HACK */
return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
};
That way, your console won't scream at you and doesn't stop the server side rendering, to which you can now carry on with your glorious day! Although I have to admit that this is a bit Hacky, but it gets the job done because all we want to do is let the server side render out the initial DOM string and then let the client-side take over.
Also Note: Don't worry about setting window as an empty object, it will be back to normal once the client-side finishes rendering.
Solution 3:
For anyone else trying to figure why their SSR fails even though they are checking if window object is undefined.
You need to check if the window reference exists, not if it's value is null!
if (typeof window === 'undefined') console.log('Window is not there')
Your window &&
and if (window)
checks with are failing because in JavaScript not declared and 'undefined' are different things.
const a = undefined;
if (a) console.log('a'); // logs nothing, since 'a' is undefined
if (b) console.log('b'); // ReferenceError: b is not defined
And answer to the original question is that whenever accessing that need 'window' object, you need to make them conditional:
return (typeof window === 'undefined') ?
'node' :
/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
Solution 4:
I've been using ReactJS.NET targeting build to client and server, and got the same problem.
The solution is to set output.globalObject
to 'this'
.
module.exports = {
// ...
output: {
// ...
globalObject: 'this'
}
};
Without that option set, it's falling back to window
which is working on client-only code.