Page HTML, CSS and JavaScript
A window's content is an ordinary web page. Its HTML, CSS and JavaScript live in the app folder and are attached the same way as on a website: with link and script tags. This page's code runs in the renderer process, so the DOM is available but Node.js is not.
Markup
Replace the contents of index.html in the project root:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
<link rel="stylesheet" href="styles.css">
<title>Notes</title>
</head>
<body>
<h1>Notes</h1>
<form id="note-form">
<textarea id="note-text" placeholder="Note text"></textarea>
<button type="submit">Add</button>
</form>
<ul id="notes"></ul>
<script src="renderer.js"></script>
</body>
</html>The styles.css and renderer.js paths are relative: the files are looked up next to index.html. The script is placed at the end of body so the elements already exist when it runs.
Styles
Create styles.css:
/* styles.css */
body {
font-family: system-ui, sans-serif;
margin: 24px;
}
textarea {
width: 100%;
min-height: 80px;
}
#notes li {
padding: 8px 0;
border-bottom: 1px solid #ddd;
}system-ui is the system font of Windows or macOS, so the app looks familiar to the user.
The page script
Create renderer.js:
// renderer.js
const form = document.querySelector('#note-form');
const text = document.querySelector('#note-text');
const list = document.querySelector('#notes');
form.addEventListener('submit', (event) => {
event.preventDefault();
const li = document.createElement('li');
li.textContent = text.value;
list.append(li);
text.value = '';
});Run npm start, type some text and click "Add" — the note appears in the list. After a restart the list is empty: the page keeps it only in memory. Saving to a file comes in the files lesson.
Loading a URL instead of a file
Instead of loadFile, a window can open an address:
// main.js
win.loadURL('https://example.com');This is used during development with Vite, when a dev server serves the page. For your own files use loadFile.
How the page differs from a website
| Website | Electron page | |
|---|---|---|
| Browser | Any | Always the built-in Chromium |
| Compatibility | Must be tested in many browsers | New CSS and JS features are available at once |
| File access | None | Through the main process |
Common mistake
Code placed directly in the HTML inside a script tag without src does not run: the Content-Security-Policy forbids inline scripts, and the console shows Refused to execute inline script. The same applies to attributes like onclick. Keep all page JavaScript in renderer.js and attach it with src.