skip to Main Content

I am trying to conditionally enable script tags in HTML using below code but it doesn’t seem to work as expected.

function loadScript() {
  document.querySelectorAll('script[type="text/skip-hydration"]').forEach((script) => {
    script.setAttribute('type', 'module');
  });
}

The value of the type attribute is updated but the scripts are not loaded.

Below are the script tags in my page:

<script src="runtime.js" type="text/skip-hydration"></script>
<script src="polyfills.js" type="text/skip-hydration">

Can someone please guide what is the issue with above code?

Update
It seems that in order to execute these script we need to add it again to the dom.

  document.querySelectorAll('script[type="text/skip-hydration"]').forEach((script) => {
    script.setAttribute('type', 'module');
    document.body.appendChild(script);
  });

Please correct me if I am wrong.

2

Answers


  1. Changing the type after a script tag has been parsed and the document has loaded doesn’t cause the browser to go back and re-evaluate a script tag, any more than modifying its text content would.

    You need to load the script from the DOM and append a new script with the appropriate type and src.

    document.querySelectorAll('script[type="text/skip-hydration"]').forEach((script) => {
      let new_script  = document.createElement('script');
      new_script.src = script.src;
      new_script.setAttribute('type', 'text/javascript');
      document.body.appendChild(new_script)
    });
    <script src="runtime.js" type="text/skip-hydration"></script>
    <script src="polyfills.js" type="text/skip-hydration"></script>
    Login or Signup to reply.
  2. You could replace each script element with a new one by cloning it, changing the type, and using Element#replaceWith.

    document.querySelectorAll('script[type="text/skip-hydration"]').forEach(script => {
        const newScript = script.cloneNode();
        newScript.type = 'module';
        script.replaceWith(newScript);
    });
    

    Alternative shorter implementation:

    document.querySelectorAll('script[type="text/skip-hydration"]')
        .forEach(script => script.replaceWith(Object.assign(script.cloneNode(), 
           {type: 'module'})));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search