window, document and local Storage in React server side rendering

1.8k views Asked by At

In my React application, I am using window object , document object and localStorage.

To avoid errors, I have set it up like:

var jsdom = require("jsdom");

var doc = jsdom.jsdom("");

if (typeof localStorage === "undefined" || localStorage === null) {
  var LocalStorage = require('node-localstorage').LocalStorage;
  localStorage = new LocalStorage('./scratch');
  global.localStorage = localStorage;

}

var win = doc.defaultView

console.log("document default viewwwwwwwwwwwwwwwwww", doc);

global.document = doc
global.window = win

function propagateToGlobal (window) {
    for (let key in window) {
        if (!window.hasOwnProperty(key)) continue
        if (key in global) continue

        global[key] = window[key]
    }
}

propagateToGlobal(win)

But in my application, I want real window, ,real localStorage and real document to be used instead of what I have set up above.

localStorage created this directory scratch.Does that mean browser localStorage would not be used now?

Also, the console statement gives this if I try to console doc variable and is being used in place of document variable which is creating problem:

Document { location: [Getter/Setter] }

This is the script I have :

<script dangerouslySetInnerHTML={{__html:(function(w,d,s,l,i){
        console.log(d.getElementsByTagName(s)[0]);
       w[l]=w[l]||[];
        w[l].push({'gtm.start':
          new Date().getTime(),event:'gtm.js'});
          var f=d.getElementsByTagName(s)[0],
          j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
           j.async=false;
        j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;
        console.log("f is",f);
        f.parentNode ? f.parentNode.insertBefore(j,f) : false;
      })(window,document,'script','dataLayer','ID')}}/>

Here getElementByTagName returns undefined and not an element as it should. How do I fix this?

1

There are 1 answers

0
peter.mouland On

basically, JSDom and the such should only be used if you would like to fake the window and document of the browser inside NodeJS. This is valid when running tests. I've not seen node-localstorage before, but i suspect the same is true of this package also.

You certainly do not want any of those packages to run within your app when on the client (in the browser).

You haven't specified which errors you have but I can only guess you are trying to run your app in node?

I would recommend removing all of them from your app completely and seeing where you get the errors. Then tackle the errors one by one. To start with ensure you only run that code on the client by using componentDidMount or something similar.

Once the app is working on the client and on the server, you could then look at how to improve / increase the amount the is rendered on the server.