Hello! Welcome back.
In our last lesson, you implemented excellent client-side validation for your contact form. You got a lot of practice manipulating individual DOM elementsβshowing and hiding error messages and changing styles based on user input.
Today, we'll build directly on those skills to tackle one of the most common tasks in web development: taking a list of data and displaying it on the page.
Your learning outcome for this lesson is to dynamically render a list of items onto the page from a JavaScript array of objects. This is a core skill you'll use to build everything from a blog feed and a photo gallery to a product catalog. It's the bridge between raw data and a user-friendly interface.

1. The Starting Point: An Array of Objects
In modern web applications, data is often structured as a JavaScript array of objects. Each object in the array represents a single item, and the properties of that object hold the details for that item.
For our exercise, imagine you want to add a section to your website to showcase your projects. Your data might look like this:
const myProjects = [
{
id: 1,
title: "Personal Profile Website",
description: "A multi-page website built with HTML, CSS, and vanilla JavaScript to showcase my skills and work."
},
{
id: 2,
title: "Theme Toggle Feature",
description: "Implemented a light/dark mode toggle using JavaScript to manipulate CSS variables and store user preference in localStorage."
},
{
id: 3,
title: "Interactive Contact Form",
description: "Built a contact form with real-time, client-side validation using the Constraint Validation API."
}
];
Our goal is to take this array and generate the following HTML structure for each project, and then inject it into our webpage.
<!-- We want to generate one of these for each project -->
<div class="project-card">
<h3>Personal Profile Website</h3>
<p>A multi-page website built with HTML, CSS, and vanilla JavaScript...</p>
</div>
2. Two Paths to Rendering: Understanding the "Why"
There are two primary methods for creating and inserting new HTML elements with vanilla JavaScript. Choosing between them often comes down to balancing readability, complexity, and performance. Since you want to know the "why" behind development practices, understanding both is crucial.
- The "Classic" DOM API: Using methods like
document.createElement(), setting properties (.textContent,.className), and then adding them to the page withNode.appendChild(). This is a very explicit, step-by-step process. - The "Modern" Template Literals: Using JavaScript's template literals (backticks
`) to build an HTML string, and then inserting it withElement.innerHTMLorElement.insertAdjacentHTML(). This often results in more readable code that looks very similar to the final HTML.
The following video does an excellent job comparing these two approaches, discussing their trade-offs in readability and performance.
Rendering in vanilla Javascript
The video 'Rendering in vanilla Javascript' by Fredrik Christenson directly compares these two fundamental methods. It will give you a great sense of the pros and cons of each.
Please watch these segments: Introduction (00:00 - 01:35): Get an overview of the two methods being compared. The 'Old' Approach (03:49 - 06:55): See how createElement and appendChild are used to build up the DOM programmatically. Notice how verbose and difficult to read it can become for even slightly complex structures. The 'New' Approach (06:55 - 08:47): See how template literals make the HTML structure much more readable and maintainable. Conclusion (08:47 - 09:27): Listen to the summary on performance and readability.
As you saw, the template literal approach is generally preferred for its excellent readability, especially as you move toward component-based frameworks like Vue.js, which use a similar templating philosophy.
3. The Modern Method in Practice: Template Literals
Let's focus on mastering the template literal method, as it's a powerful and common pattern.
The process is straightforward:
- Get a reference to the container element in your HTML where the list will go.
- Use an array method like
.forEach()to loop through your data array. - Inside the loop, construct an HTML string for a single item using a template literal, injecting data from the current object (e.g.,
${project.title}). - Use
container.insertAdjacentHTML('beforeend', htmlString)to add the new HTML to the end of the container.
We use insertAdjacentHTML('beforeend', ...) because it's typically more performant than innerHTML += .... While innerHTML += ... forces the browser to re-parse all the HTML inside the container on every iteration, insertAdjacentHTML simply adds the new element without disturbing the existing ones.
This next video provides a perfect, concise demonstration of this exact pattern.
Read JSON File into HTML with JavaScript Fetch API
The video 'Read JSON File into HTML' by ByteGrad shows this pattern in action. The video uses fetch to get the data, which we'll cover in a future lesson. For now, focus only on what happens after the data is availableβthe iteration and rendering.
Watch the section from 03:37 to 05:48. Pay close attention to: How forEach is used to iterate over the data array. The use of a template literal (the string with backticks `) to create the <li> element. The use of listEl.insertAdjacentHTML('beforeend', ...) to efficiently add each new item to the list.
4. Your Turn: Building a Projects Section
Now it's time to apply this to your personal profile site. Let's create a new page to display a list of your projects.
Task:
-
Create the HTML: In your project folder, create a new file named
projects.html. Set up the basic HTML5 structure and link your existing stylesheet. Inside the<body>, add a header, navigation (you can copy this from your other pages), and a<main>section. Inside<main>, add an empty container for your project list:<h1>My Projects</h1> <div id="project-list-container"></div> -
Create the JavaScript: Create a new file,
projects.js. In this file, start with themyProjectsarray from earlier in this lesson. -
Write the Rendering Logic: Follow the pattern you just learned. Here's a skeleton to guide you. Try to fill in the blanks yourself!
// projects.js const myProjects = [ { id: 1, title: "Personal Profile Website", description: "A multi-page website built with HTML, CSS, and vanilla JavaScript to showcase my skills and work." }, // ... (add the other projects from the example above) ]; // 1. Select the container element from projects.html const projectContainer = document.querySelector('#project-list-container'); // 2. Loop through the myProjects array myProjects.forEach(project => { // 3. For each project, create an HTML string using a template literal const projectHTML = ` <div class="project-card"> <h3>${project.title}</h3> <p>${project.description}</p> </div> `; // 4. Insert the HTML into the container projectContainer.insertAdjacentHTML('beforeend', projectHTML); }); -
Link and View: Link your new
projects.jsfile at the bottom ofprojects.html(just before the closing</body>tag) and open it in your browser. You should see your list of projects rendered on the page! Feel free to add some CSS to style the.project-cardelements.
5. For Your Reference: The createElement Approach
While we're focusing on the modern method, it's valuable to see a full example of the createElement approach. The MDN Web Docs, an essential resource for web developers, has a great tutorial that builds a dynamic shopping list using this method.
To solidify your understanding of the 'classic' DOM API method, review this example from the MDN Web Docs.
Read through the JavaScript code in the section titled 'Creating a dynamic shopping list'. You don't need to build this yourself. Instead, focus on the process: see how every element (li, span, button) is created with document.createElement(), its content is set, and then it's appended to a parent with appendChild().
This exercise highlights the verbosity of the method but also its explicit nature, which can be useful in certain scenarios.
Conclusion
Great job! You have now learned a fundamental technique for building dynamic web pages. By taking a structured array of data and rendering it into the DOM, you can now create much more complex and data-driven user interfaces.
Key Takeaways:
- Data in web applications is commonly structured as an array of objects.
- The
forEach+ template literal +insertAdjacentHTMLpattern is a modern, readable, and efficient way to render lists of data. - The older
createElementandappendChildmethod is more verbose but gives you fine-grained programmatic control over element creation. - Understanding both methods allows you to choose the right tool for the job and comprehend a wider range of existing code.
So far, our data has been "local"βhardcoded directly in our JavaScript file. But what if the data lives on a server somewhere? To get it, we need to make a request, which takes time. This brings us to our next topic: asynchronous JavaScript. In the next lesson, we will start with setTimeout to understand how JavaScript handles time-delayed operations, which will prepare us to use the fetch API to retrieve live data from the web.