Windows and the renderer
Render notes safely
Keep note data in renderer state and draw user text without turning it into executable HTML.
10 minute lesson
Renderer state can be ordinary browser JavaScript. Start src/renderer.js with local state:
let notes = []
let selectedId = null
const list = document.querySelector('#notes')
const titleInput = document.querySelector('#title')
const bodyInput = document.querySelector('#body')
Render each title with textContent:
function renderNotes() {
list.replaceChildren()
for (const note of notes) {
const button = document.createElement('button')
button.type = 'button'
button.textContent = note.title || 'Untitled'
button.addEventListener('click', () => selectNote(note.id))
const item = document.createElement('li')
item.append(button)
list.append(item)
}
}
Do not place note content into innerHTML. Notes are user data, not markup. textContent keeps a note such as <img onerror=...> as visible text.
The code creates DOM nodes instead of building an HTML string. This keeps escaping decisions local and lets each button receive one explicit listener.
Use stable note IDs for selection. An array position changes when a note is inserted or deleted, so it is not a durable identity.
Test hostile-looking content now:
notes = [{
id: 'test-note',
title: '<img src=x onerror=alert(1)>',
body: '<script>alert(1)</script>'
}]
The strings should appear as text. No request, alert, or script execution should occur. Keep this case in the renderer test checklist because later refactors can reintroduce unsafe HTML.
Rendering safely is separate from validating size and shape. The main process will still validate every note before saving it.
Lesson completed