Control Flow Logic
The output tags (<%= %>) handle display, but true dynamism requires logic. To conditionally render content or iterate over data collections, EJS uses “Scriptlet” tags (<% %>) that allow you to execute standard JavaScript code inside your views.
Scriptlet Tags (<% %>)
Section titled “Scriptlet Tags (<% %>)”Scriptlet tags accept standard JavaScript syntax. Unlike output tags, they do not print their result to the page; they are used strictly for control flow operations like loops and if-statements.
Iteration
Section titled “Iteration”To render a list of items, we break a standard JavaScript for loop across multiple lines of HTML. The opening bracket { lives in the first scriptlet, and the closing bracket } lives in its own scriptlet at the end.
<ul> <% things.forEach(thing => { %> <li> <a href="/things/<%= thing.id %>" style="color: inherit; text-decoration: none; display: block; width: 100%;"> <%= thing.name %> </a> </li> <% }) %></ul>Conditional Rendering
Section titled “Conditional Rendering”Scriptlets allow you to perform presence checks or alter the output based on data states. This pattern handles scenarios like “Empty States” or access control.
<% if (things.length === 0) { %> <!-- Rendered if the condition is true --> <div class="alert">Nothing found in the database.</div><% } else { %> <!-- Rendered if the condition is false --> <ul> <% things.forEach((thing) => { %> <li><%= thing.name %></li> <!-- conditional output --> <% if (!thing.active) { %> (Inactive) <% } %> <% }) %> </ul><% } %>Note that we can use any valid JavaScript, including Array methods like .forEach(), which are often cleaner than standard for loops in templates.