JavaScript Curriculum
Reading & Writing Content
easyThe 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
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.
XSS — The innerHTML Trap
Setting innerHTML with user-provided content is the most common DOM security mistake:
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!Live Editor — innerHTML vs textContent
See exactly how both properties treat your content:
Our Specials
Today's featured brew: Ethiopian Pour Over
- Floral aroma
- Bright acidity
- Clean finish
£4.50 · Limited availability
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.
Reading & Writing Content
easyThe 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
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.
XSS — The innerHTML Trap
Setting innerHTML with user-provided content is the most common DOM security mistake:
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!Live Editor — innerHTML vs textContent
See exactly how both properties treat your content:
Our Specials
Today's featured brew: Ethiopian Pour Over
- Floral aroma
- Bright acidity
- Clean finish
£4.50 · Limited availability
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.