---
title: "How to Use innerHTML in JavaScript, Plus Alternate Methods | CoderPad"
description: "Walk through the pros & cons of using the JavaScript innerHTML property and how to use it safely without exposing yourself to XSS attacks."
canonical: "https://coderpad.io/blog/development/javascript-innerhtml/"
last_modified: "2026-04-15 16:21:09"
---
[Back to blog](https://coderpad.io/blog/)

# How to Use innerHTML in JavaScript, Plus Alternate Methods

September 21, 2022 5 Minute Read

By Keshav Malik

[Development](https://coderpad.io/blog/development/)

If you’re creating any dynamic web page these days, making sure you have relevant and up-to-date information is vital.

Whether it’s showing stock quotes, the current time, the user’s name, or any other piece of info that changes with time or user, you’ll want to make sure you’re regularly updating this dynamic content to produce the best experience for your users.

Luckily for you, we can associate these dynamic pieces of information with HTML elements and easily display their current state using the innerHTML property.

This blog post will walk you through the pros and cons of using the`innerHTML`property and how you can use it safely without opening the doors to potential [Cross-Site scripting (XSS) attacks](https://owasp.org/www-community/attacks/xss/).

## What is innerHTML in JavaScript?

`innerHTML`is an HTML element property that has two uses for web developers:

1) You can use it to get the internal HTML content of any HTML element as an HTML string.

2) You can also use it to set or change elements’`innerHTML`content.

Take the following HTML example:

```
<div id=”someDivElement”>
  <span>Hello World</span>
</div>Code language: HTML, XML (xml)
```

To access the innerHTML you’ll first need to access the element itself with`getElementById()`:

`const someDivElement = document.getElementById(“someDivElement”);`

Then we can access the`innerHTML`:

`console.log(someDivElement.innerHTML);`

This will give us`" <span>Hello World</span> "`as a string. And if you want to modify the`innerHTML`property of the element, it can be achieved in the following way:

`someDivElement.innerHTML = “<span>Something just like this…</span>”;`

Here’s an example that can be used by to-do apps where list items are appended to an existing list:

```
const todos = ["Exercise",
  "Have milk",
  "Buy bread",
  "Walk the dog",
  "Sleep timely :)"
];

const todoListPreview = document.getElementById(“tdlst-preview”); /* returns an <ol> */ element

todos.forEach((todo) => {
  todoListPreview.innerHTML += `<li>${todo}</li>`;
});

Code language: JavaScript (javascript)
```

This will add all the to-do items as`<li>`tags in our ordered list element. These are the ways we can get and set the`innerHTML`properties.

However – as with any piece of code – there can be exceptions. A common one you may see with`innerHTML`is the`SyntaxError`, which is thrown when the provided HTML string is ill-formed. Here’s an example:

```
someDivElement.innerHTML = “<span>William Bradley "Brad" Pitt</span>”Code language: HTML, XML (xml)
```

The moment the browser parses this script,`" Brad "`is perceived as an unknown identifier because of the double quotes, and the`SyntaxError`exception is thrown.

## When not to use innerHTML

Using`innerHTML`is fine if you’re using it to get the value of an element’s`innerHTML`content. Things change, however, if it’s used to set values, as it accepts all HTML tags, including the`script`tag. This means you could potentially open up a portal to your cookies and users’ personal information via a Cross Site Scripting (XSS) attack.

An XSS attack is a type of web security vulnerability that allows an attacker to inject malicious code into a webpage. Then that code is executed by the web browser when an unsuspecting user visits the page.

Take the example below that allows a bad script to send a user’s cookies to its server, which then can be used to impersonate the actual user and perform malicious actions:

```
document.getElementById(“someLogoutButton”).innerHTML = “<script>callHome(document.cookie);</script>”;Code language: HTML, XML (xml)
```

Fortunately, the World Wide Web Consortium (W3C) has since released a standard on [dynamic markup insertion in HTML](https://www.w3.org/TR/2008/WD-html5-20080610/dom.html) that states that`script`elements are not executed when inserted using`innerHTML`. However, hackers have found other ways to carry out XSS attacks.

Let’s take the following example of the`img`tag. It has an`onerror`attribute that accepts JavaScript and is allowed to be run.

`<img src=123>

Once browsers parse this tag, the value of`src`is invalid as browsers expect a URL. Thus, an error will be thrown, and as the image tag has an`onerror`listener, the script inside will be executed.

### How to use innerHTML without creating XSS vulnerabilities

To prevent XSS issues, you always want to sanitize your user input, especially when it’s going to be rendered as-is.

Say you’re building a [WYSIWYG](https://en.wikipedia.org/wiki/WYSIWYG) editor in which you’re letting users save their HTML content in your database via innerHTML. Since you can’t trust your users’ input, you’ll need to implement some sanitization to prevent them from adding malicious code.

There are a lot of [open-source libraries](https://coderpad.io/blog/development/10-javascript-data-visualization-libs/) available that provide this sanitization service. One of my favorites is [sanitize-HTML](https://www.npmjs.com/package/sanitize-html), which provides HTML cleaning for browser and node environments.

`npm install sanitize-HTML`

The library is fairly easy to use. Here are a few examples:

```
// the es module way
import sanitizeHtml from 'sanitize-html';
// the commonjs way
const sanitizeHtml = require('sanitize-html');

sanitizeHtml('<img src=x>); // returns ""

sanitizeHtml('<svg><g/onload=alert(2)//<p>'); // returns ""

sanitizeHtml('<p>abc<iframe//src=jAva&Tab);script:alert(3)>def</p>'); // returns <p>abcdef</p>

sanitizeHtml('<TABLE><tr><td>HELLO</tr></TABL>'); // returns "<table><tr><td>HELLO</td></tr></table>"

sanitizeHtml('<UL><li><A HREF=//google.com>click</UL>'); // returns "<ul><li><a href=\"//google.com\">click</a></li></ul>"
Code language: JavaScript (javascript)
```

NOTE: You can try the library out at [RunKit](https://npm.runkit.com/sanitize-html).

By default, sanitize-HTML has a predefined set of rules on what tags and attributes to allow and remove/escape; however, it can be tailored ([refer to the documentation](https://www.npmjs.com/package/sanitize-html)) further per the developers’ requirements.

>

![⚠️](https://coderpad.io/assets/emoji/26a0.svg) Always sanitize HTML string inputs on both the front and back end to reduce the attack vector substantially.

## innerHTML vs. createElement

createElement is an alternative method of innerHTML, so here we’ll look at the two.

`createElement`is faster, as browsers are not required to parse the HTML string and then build a node tree out of it; it also doesn’t have to attach event listeners as`innerHTML`does. Using`innerHTML`will cause browsers to reparse and recreate all DOM nodes inside the element whose`innerHTML`is modified.

However, if you’re writing a dynamic solution like a Markdown to HTML converter with a real-time preview, then`innerHTML`is the way to go as it is a “one-size-fits-all” approach. This is precisely what’s required for this particular conversion and real-time preview. Building the same logic with`createElement`would be a pain and render highly coupled logic with unextendable code.

We can see this if we take the same to-do list example discussed above but use`createElement`instead of`innerHTML`:

```
const todos = ["Exercise",
  "Have milk",
  "Buy bread",
  "Walk the dog",
  "Sleep timely :)"
];
const todoListPreview = document.getElementById(“tdlst-preview”); // returns an <ol> element
todos.forEach((todo) => {
  todoListPreview.innerHTML += `<li>${todo}</li>`;
  const listItemElement = document.createElement(“li”);
  listItemElement.textContent = todo;
  todoListPreview.appendchild(listItemElement);

});
Code language: JavaScript (javascript)
```

This will work for this particular problem, but it’s not a scalable approach.

You’d be adding a lot of work for yourself and your team if, for example, you wanted to build a Rich Text Editor where you have to write separate logic for each of the new functionalities you might add.

Using innerHTML with a simple HTML sanitizer is a much more efficient and practical approach.

## Conclusion

In HTML, assigning a string to the`innerHTML`property is okay in some situations. However, if you can’t be sure of what the string contains—for example, if a user provides it and it is possibly malicious—it’s best to use`createElement`or sanitize the input before storing it in a database.

The open-source “sanitization” libraries strip off specific tags and attributes to make the desired HTML string XSS proof. Sanitization should be done on both the frontend and backend as a best practice to help reduce the risk of XSS attacks. When implementing sanitization on the frontend, it should be done at the time of render when the user provides input. And, on the backend, it should be done before storage in the database.

This post was written by Keshav Malik. [Keshav](https://theinfosecguy.xyz/) is a full-time developer who loves to build and break stuff. He is constantly looking for new and exciting technologies and enjoys working with diverse technologies in his spare time. He loves music and plays badminton whenever the opportunity presents itself.

## Subscribe for more CoderPad insights

## Trending Articles

Previous slide Next slide [Development

## What is Prompt Engineering?

Introducing AI tools such as ChatGPT and Bard helps increase the efficiency of tasks such as data generation, code generation and completion, text summarization, etc. How were these AI tools trained to answer almost every question you ask them? The answer, prompt engineering, is discussed in this blog post.

Read the post](https://coderpad.io/blog/development/what-is-prompt-engineering/) [Development

## A Guide To Using React’s useCallback() Hook

Are you looking to optimize your React applications? Have you heard of the useCallback hook? useCallback is a powerful React hook that helps you optimize your application by preventing unnecessary re-renders. In this post, we'll dive into React's useCallback() hook, define referential equality and callback functions and how to tie it all together.

Read the post](https://coderpad.io/blog/development/a-guide-to-using-reacts-usecallback-hook/) [Development

## MySQL vs. PostgreSQL: How Do They Compare?

A database is a convenient tool that allows users to access information, maintain records, and apply commonly used operations, such as insertion, modification, deletion, and data organization. Learn about MySQL vs PostgreSQL, their features, advantages, and disadvantages. Finally, check out which one is the best choice for you.

Read the post](https://coderpad.io/blog/development/mysql-vs-postgresql-how-do-they-compare/) [Development

## PostgreSQL LIKE Operator: A Detailed Guide

When using databases, searching for values that match a given pattern is a familiar necessity. Learn how you can retrieve entries with queries including a particular string using Postgres LIKE operator.

Read the post](https://coderpad.io/blog/development/postgresql-like-operator-a-detailed-guide/) [Development

## How To Use DataProvider In TestNG With Examples

When it comes to testing there are many tools and techniques available. In this post, we'll discuss how to use DataProvider with TestNG.

Read the post](https://coderpad.io/blog/development/how-to-use-dataprovider-in-testng-with-examples/) [Development

## How To Get Up And Running With Django Migrations: A Guide

Django migrations are a way of handling the application of changes to a database schema. By following the steps outlined in this guide, you can easily set up and use migrations in your Django projects.

Read the post](https://coderpad.io/blog/development/how-to-get-up-and-running-with-django-migrations-a-guide/) [Development

## Writing A Parameterized Test In JUnit With Examples

A JUnit parameterized test allows you to decouple data from structure, generating cleaner and more reliable tests. Learn more in this guide.

Read the post](https://coderpad.io/blog/development/writing-a-parameterized-test-in-junit-with-examples/) [Development

## How To Use Assert In JUnit With Examples

The JUnit Assert class is what you use to write unit testing assertions in JUnit. Learn more about it in this guide, full of examples.

Read the post](https://coderpad.io/blog/development/how-to-use-assert-in-junit-with-examples/) [Development

## A Simple Guide To TypeORM: What It Is And How To Use It

Considering current languages have object-oriented programming features, most database management systems are based on the relational model, with tables instead of objects. For these reasons, mapping relational objects is very important in development. In this article, you will learn what TypeORM, one of the main tools used today, is.

Read the post](https://coderpad.io/blog/development/a-simple-guide-to-typeorm-what-it-is-and-how-to-use-it/) [Development

## Using PreparedStatement in JDBC With Examples

In this post, we'll see why and how to work with JDBC and PreparedStatement. We will also learn along with examples using code.

Read the post](https://coderpad.io/blog/development/using-preparedstatement-in-jdbc-with-examples/) [Development

## React vs React Native: The Differences Explained

React and React Native are similar in that they both allow web developers to build applications based on the unique concept of components. But the two frameworks do this in radically different ways. In this post, we cover the key differences between react and react native frameworks, implementation, and which is an appropriate choice.

Read the post](https://coderpad.io/blog/development/react-vs-react-native-the-differences-explained/) [Development

## Logging in Django

The most challenging part of fixing a problem is identifying it. Unfortunately, this statement is exceptionally true when it comes to debugging. Learn how to use the power of logging into your Django applications to improve your debug process in this article.

Read the post](https://coderpad.io/blog/development/logging-in-django/)

## Hire with confidence.

See why engineering teams trust CoderPad to evaluate developers with realistic, AI-ready hiring workflows.

[Request a demo](https://coderpad.io/sales/)
