JavaScript in the browser
Build a small interactive page
Combine DOM selection, events, arrays, local storage, fetch, and error handling in one small browser project.
8 minute lesson
Build a page that lets a visitor save a short reading list.
Start with one state array. Every add, remove, and load action updates that array, persists it, then renders from it. Do not update the DOM independently or you will create two sources of truth.
Use a small item shape:
{
id: crypto.randomUUID(),
title: 'JavaScript modules',
url: 'https://example.com/modules'
}
On startup, read local storage inside try/catch. JSON can be missing, malformed, or from an older version of the application. Validate that the parsed result is an array before accepting it.
Handle the form’s submit event. Trim the title, parse the URL with new URL(), reject unsupported protocols, and show the error next to the relevant field. Build DOM elements with textContent and attributes rather than interpolating untrusted text into innerHTML.
Render each item with a real link and a remove button. Use the stable id to remove the intended item, including when two titles are identical. Keep keyboard focus somewhere sensible after adding or removing an item.
Add a button that loads one suggested item with fetch(). Show a useful message if the request fails.
Model the request states explicitly: idle, loading, success, empty, and error. Disable only the action that would create a duplicate request. Check response.ok; a fulfilled fetch() promise can still represent an HTTP error.
Test these paths before considering the project complete:
- keyboard-only add and remove
- empty and malformed values
- duplicate titles with different URLs
- malformed saved JSON
- a failed and a slow network request
- a page reload after every state change
The goal is not visual polish. It is tracing one reliable data flow through events, arrays, validation, storage, network work, rendering, and recovery.
Lesson completed