Frontend Master

JavaScript Curriculum

Reading & Writing Content
+50 XP

Reading & Writing Content

easy
~25 min·50 XP

The coffee shop wants to update menu item names and prices dynamically from a database. You need to write content into the DOM safely — without accidentally running malicious code from user input.

Reading & Writing Content

Three properties give you access to what's inside an element. They look similar but behave very differently — especially when writing content from user input.

textContent vs innerHTML vs innerText

content-properties.js
Element HTML
el.textContent✓ safe to set
→ "Espresso — £2.50"

Returns all text, including hidden elements. Strips all HTML tags. Safe for reading. Setting it escapes HTML — prevents XSS.

el.innerHTML⚠ XSS risk when setting
→ "<strong>Espresso</strong> — <em>£2.50</em>"

Returns the raw HTML string including tags. Setting it parses and renders HTML. ⚠ Never set innerHTML from user input — XSS risk.

el.innerText✓ safe to set
→ "Espresso — £2.50"

Returns visible text only (respects CSS display:none). Slower than textContent because it triggers layout. Use textContent unless you need CSS-aware text.

💡Default to textContent
Use textContent for reading and writing plain text — it is fast, safe, and straightforward. Only reach for innerHTML when you genuinely need to inject HTML markup, and only when you fully control the content being injected.

XSS — The innerHTML Trap

Setting innerHTML with user-provided content is the most common DOM security mistake:

xss-safety.js
🚨 XSS vulnerable

Directly inserting user input into innerHTML — the most common XSS mistake.

// User types: <img src=x onerror="alert('hacked!')">
const userInput = searchInput.value

// 🚨 NEVER do this:
resultsDiv.innerHTML = `
  <p>Results for: ${userInput}</p>
`
// The <img> tag executes JavaScript!
⚠️XSS can steal sessions and data
Cross-Site Scripting (XSS) lets attackers inject JavaScript that runs in your users' browsers. It can steal cookies, hijack sessions, redirect users, or silently exfiltrate data. Always use textContent or createElement + textContent when inserting user-provided content.

Live Editor — innerHTML vs textContent

See exactly how both properties treat your content:

live-editor.js
Editor
Preview — el.innerHTML

Our Specials

Today's featured brew: Ethiopian Pour Over

  • Floral aroma
  • Bright acidity
  • Clean finish

£4.50 · Limited availability

⚠ innerHTML renders HTML — safe here in a controlled demo, but never use with user-supplied content
ℹ️innerText vs textContent
innerText is CSS-aware — it skips elements with display:none and triggers a layout recalculation. textContent reads all text including hidden elements and is significantly faster. Unless you specifically need CSS-aware text extraction, always use textContent.

Your Challenge

In the console: read document.querySelector('h1').textContent. Then safely add a new menu item — create a div.card, set an h3.textContent inside it, and append it to .cards. Never use innerHTML with a string you did not write yourself.

Challenge

Select the h1 and read its textContent. Then select a .card and read its innerHTML — notice the difference. Create a new <p> element, set its textContent to user-provided text, and append it to the card safely.

textContentinnerHTMLinnerTextXSSsecuritycreateElementDOMPurifycontent-writing
Reading & Writing Content | Nexus Learn