yellowpisagor
yellowpisagor

Reputation: 156

Broken script when added to headers in WordPress

I write a WordPress Plugin which provides adding scripts to header. When I try to add code snippets of our service

<script src="url/index.js"></script>
<script>
  var foo = new window.Name("token");
  foo.init();
</script>

to head, I got some errors.

Uncaught (in promise) TypeError: Cannot read property 'appendChild' of null
at r.<anonymous> (index.js:176)
at L (index.js:47)
at Generator._invoke (index.js:47)
at Generator.t.(:8000/anonymous function) [as next] (url/index.js:47:4580)
at r (index.js:174)
at c (index.js:174)
at index.js:174
at new Promise (<anonymous>)
at new r (index.js:36)
at r.<anonymous> (index.js:174)

and

Uncaught TypeError: Cannot read property 'appendChild' of null
at i.value (index.js:178)
at r.value (index.js:180)
at (index):41

.

The url returns our script code which is rendered by Babel.

When I add any standard html code like <html></html> or <p></p> before the script,

<p></p>
<script src="url/index.js"></script>
<script>
  var foo = new window.Name("token");
  foo.init();
</script>

it works clearly. What about any html code? I can't understand. I solve it by adding <html></html> without broken website. I try to learn problem.

Upvotes: 0

Views: 148

Answers (1)

markmoxx
markmoxx

Reputation: 1532

It's hard to tell without seeing what's in your url/index.js file, but it's probably trying to append a node to the <body> element, or a child of it before it exists. It will not exist yet if you are calling this script in the <head> section.

The reason the <p></p> fixes it is that if the browser receives the following:

<head>
  <script>
    console.log(document.body);
  </script>
</head>

It sees it is invalid HTML, and so it re-interpreted as:

<html>
  <head>
    <script>
    console.log(document.body);
    </script>
  </head>
  <body></body>
</html>

- the body does not exist by the time the script is run, so the console logs null.

If the browser receives:

<p>Paragraph</p>
<head>
  <script>
    console.log(document.body);
  </script>
</head>

...it is again invalid HTML, and is re-interpreted as

<html>
  <head></head>
  <body>
    <p>Paragraph</p>
    <script>
      console.log(document.body);
    </script>
  </body>
</html>

...and the body element exists when the script runs, so it will log the body element to the console.

In summary: You need to make sure all of your HTML is valid, and that your script only tries to append something to an element which already exists.

Upvotes: 2

Related Questions