Why Is Using innerHTML a Bad Idea?

The innerHTML property enables you to alter content of an HTML element. It's one of the simplest method for dynamically adding or editing HTML information.

Despite its simplicity, why is it considered “bad” and is frowned upon?

Here are some drawbacks that make it an unfavourable choice to use:

1. Cross-Site Scripting (XSS) Threats

An XSS attack using innerHTML works by injecting malicious code into your website, which it then uses to carry out an attack. This is possible because innerHTML renders a complete markup and not just text.

This might then provide an attacker the opportunity to steal confidential user information or conduct other illicit activities on the site.

For example

// Example of vulnerable code using innerHTML
var userInput = '<script>alert("XSS attack!");</script>';
document.getElementById("someElement").innerHTML = userInput;

When someElement is rendered, the script will be executed, leading to an alert with "XSS attack!".

2. Slow in Dynamically Updating HTML Content

innerHTML requires the browser to parse and render the element's whole HTML content, and this might take a while for larger elements or those elements that are updated regularly.

3. Can break the webpage

There is no proper validation provided by innerHTML, so any HTML code can be used. For example, unclosed tags or malformed HTML could disrupt the existing structure of the document.

<div id="exampleDiv">
  <p>This is a paragraph.</p>
</div>

<script>
  // Injecting HTML with unclosed tags using innerHTML
  document.getElementById('exampleDiv').innerHTML = '<p>Updated paragraph';

  // The unclosed <p> tag can disrupt the document structure

  // Attempting to add more content
  document.getElementById('exampleDiv').innerHTML += '<span>Additional content</span>';
</script>

4. Appending is not supported

Appending to an HTML tag using innerHTML results in the entire tag being re-parsed, introducing a slowdown in performance.

<p id="sentence">Good Morning</p>;
sentence = document.getElementById("sentence");

// The whole element have re-parsed
sentence.innerHTML += "<p> Hello world </p>";

5. Entire Content is replaced

When you use innerHTML to modify an element's content, it replaces the entire content of that element, including all child elements. This behavior might not be desirable if you only want to make a small change within the element.

<div id="exampleDiv">
  <p>This is the original content.</p>
</div>

<script>
  // Using innerHTML to make a change within the element
  document.getElementById('exampleDiv').innerHTML = '<p>Updated content</p>';

  // The entire content, including the original paragraph, is replaced
</script>

6. Preserves event handlers attached to any DOM elements

New elements created by setting innerHTML do not automatically retain attached event handlers. Manual tracking and attachment of event handlers are required, which can potentially lead to memory leaks in certain browsers.

<button id="myButton">Click me</button>

<script>
  // Initial event handler attached to the button
  document.getElementById('myButton').addEventListener('click', function() {
    alert('Button clicked!');
  });

  // Simulating dynamic content update using innerHTML
  document.body.innerHTML = '<button id="myButton">Updated Button</button>';

  // Attempting to click the updated button won't trigger the alert
  document.getElementById('myButton').addEventListener('click', function() {
    alert('Updated Button clicked!');
  });
</script>

Get my free, weekly JavaScript tutorials

Want to improve your JavaScript fluency?

Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.

Join today, and level up your JavaScript every Sunday!

Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.

- Remi Egwuda