Element. innerHTML
Reads or replaces an element’s content as HTML code.
- Returns
- A string with the HTML code of the element’s content.
Example
#const menu = document.querySelector('#menu')
console.log(menu.innerHTML)
const items = ['Courses', 'Ranking', 'Profile']
menu.innerHTML = items.map((item) => `<li>${item}</li>`).join('')
console.log(menu.children.length)
console.log(menu.innerHTML)Definition and usage
#The innerHTML property returns the HTML code of all of an element’s children as a string. Assigning a new string removes the existing content, and the browser parses the text as HTML and builds new elements from it.
It’s a convenient way to insert a larger fragment, for example one built with a template literal. Keep in mind, though, that every assignment destroys the old elements along with any event handlers attached to them and any text typed into form fields. innerHTML += also rebuilds the whole content from scratch.
The biggest risk is security. Inserting text from a user through innerHTML opens the door to an XSS attack: someone could smuggle in markup with code that runs on your page. Insert external data through textContent, or build elements with createElement().
Syntax
#const html = element.innerHTML
element.innerHTML = htmlStringMore examples
#const box = document.querySelector('#box')
const oldButton = document.querySelector('#buy')
box.innerHTML += '<p>Promo: 20% off</p>'
console.log(document.querySelector('#buy') === oldButton)
console.log(oldButton.isConnected)After +=, the browser rebuilt the content from scratch. The new button looks the same, but it’s a different element, and the event handler attached to the old one stopped working.
const greeting = document.querySelector('#greeting')
const userName = '<em>Jack</em>'
greeting.innerHTML = `Hi, ${userName}!`
console.log(greeting.querySelector('em') !== null)
greeting.textContent = `Hi, ${userName}!`
console.log(greeting.querySelector('em') !== null)Through innerHTML, the markup in the string becomes real elements. textContent shows it as plain text, which is why it’s safe for data from a user.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Never insert data from a user or an API through
innerHTMLwithout sanitizing it. UsetextContentfor text. - Avoid
innerHTML +=in a loop, since every step rebuilds the whole content. Build the full string first, or useinsertAdjacentHTML(). - To clear an element,
element.innerHTML = ""orelement.replaceChildren()is enough.
Related entries
#- innerHTML vs textContentinnerHTML reads and sets an element’s HTML markup, parsing the string into new elements, while textContent reads and sets plain text, with no markup.
- Node.textContentReads or sets all of an element’s text, without HTML markup.
- Element.insertAdjacentHTML()Parses a string as HTML and inserts the resulting elements at a chosen position relative to an element.
- document.createElement()Creates a new HTML element with the given tag name, ready to be inserted into the page.
- Template literalsText templates in backticks: insert values with ${} and span multiple lines.
- Element.append()Adds elements or text at the end of an element’s content.
Spotted a mistake or missing an example? Write to us.