3. EJS
1. Introduction
Section titled “1. Introduction”EJS (Embedded JavaScript Templating) is a simple templating language that lets you generate HTML markup with plain JavaScript.
Features
Section titled “Features”- Use plain JavaScript: Unlike
pug,ejsuses JS! - Fast development time: Don’t waste time learning complex new syntax or preprocessing data for proper rendering.
- Simple syntax: Just write JavaScript that emits the HTML you want, and get the job done!
- Speedy execution: We all know how fast V8 and the other JavaScript runtimes have gotten. EJS caches the intermediate JS functions for fast execution.
- Easy debugging: It’s easy to debug EJS errors: your errors are plain JavaScript exceptions, with template line-numbers included.
- Active development: EJS has a large community of active users, and the library is under active development. We’re happy to answer your questions or give you help.
2. Example
Section titled “2. Example”Create a file hello.ejs and place it in .\views folder
🗂 Folder structure:
Section titled “🗂 Folder structure:”DirectorytestNodeProject/
Directoryviews/
- hello.ejs
- server.js
- package.json
In server.js set the view engine to ejs
const express = require('express');const app = express()
// Set the view engineapp.set( 'view engine', 'ejs' );
// Set handler for the root '/'app.get('/', (req, res) => { res.render('hello', {theTitle: 'This is the Title'}); // this will look for the file 'hello.ejs' in './views' folder // second parameter to render(...) method is optional});<!DOCTYPE html><html lang="en"><head> <title>Hello World! <%= locals.theTitle || "Default Value" %></title></head><body> <h1>Hello World!</h1> <div class="remark"> <p>EJS rocks!!</p> </div></body></html>It is important to use locals.theTitle instead of theTitle in the .ejs file above since the page will report an error if the parameter is not defined during the call to res.render(...) method. In contrast, locals dictionary will always be defined internally when called res.render(...) method. if a parameter (i.e. theTitle) is not defined, locals.theTitle will simply return nothing.
Rendered output, when http://localhost:3000/ is accessed
<!DOCTYPE html><html lang="en"><head> <title>Hello World! This is the Title</title></head><body> Hello World This is the Title</body></html>3. Control Flow Statements
Section titled “3. Control Flow Statements”Similar to JavaScript, EJS provides a syntax for using conditional logic within your HTML templates. Following demonstrate practical examples of using conditional statements with the EJS template
3.1 Conditional Statements
Section titled “3.1 Conditional Statements”Below is an example of using a if conditional statement in ejs
<% if(true){ %> <h1>foo</h1> <% } else { %> <h1>bar</h1> <% } %>{% endcapture %}3.2 Looping Statements
Section titled “3.2 Looping Statements”Below is an example of using a for loop statement in ejs
const express = require('express');const app = express()
// Set the view engineapp.set( 'view engine', 'ejs' );
// Set handler for the root '/'app.get('/', (req, res) => { res.render('index', { data: [ { id: 1, name: "bob" }, { id: 2, name: "john" }, { id: 3, name: "jake" }, ] });});<table> <% for(var i=0; i < data.length; i++) { %> <tr> <td><%= data[i].id %></td> <td><%= data[i].name %></td> </tr> <% } %></table>Rendered output, when http://localhost:3000/ is accessed
<table><tbody> <tr> <td>1</td> <td>bob</td> </tr> <tr> <td>2</td> <td>john</td> </tr> <tr> <td>3</td> <td>jake</td> </tr></tbody></table>4. Partials and Layout Systems
Section titled “4. Partials and Layout Systems”Partials are reusable view components — like headers, footers, navbars — that you can include in multiple EJS pages.
Think of them like “HTML includes.”
4.1 ✅ Creating and Using Partials
Section titled “4.1 ✅ Creating and Using Partials”📁 Folder structure
Section titled “📁 Folder structure”Directoryviews/
Directorypartials/
- header.ejs
- footer.ejs
- index.ejs
- about.ejs
<header> <h1>My Website</h1> <nav> <a href="/">Home</a> | <a href="/about">About</a> </nav></header><footer> <p>© 2025 Nadith's Site</p></footer><!DOCTYPE html><html><head> <title>Home</title></head><body> <% include partials/header %>
<h2>Welcome to the Home Page</h2>
<% include partials/footer %></body></html>💡 EJS uses the <% include path %> syntax to import partials.
4.2 📦 What Is express-ejs-layouts?
Section titled “4.2 📦 What Is express-ejs-layouts?”By default, EJS doesn’t support layouts like some other engines (e.g., Pug or Handlebars).
The express-ejs-layouts package helps you:
- Define a master layout
- Inject your content (
<%- body %>) into it from different views
🔧 Setup:
Section titled “🔧 Setup:”npm install express-ejs-layoutsconst express = require('express');const app = express();const expressLayouts = require('express-ejs-layouts');
app.set('view engine', 'ejs');app.use(expressLayouts); // ⬅️ Add this🗂 Folder structure:
Section titled “🗂 Folder structure:”Directoryviews/
- layout.ejs
- index.ejs
- about.ejs
<!DOCTYPE html><html><head> <title><%= title %></title></head><body> <%- body %> <!-- All page content will go here --></body></html><h1>Home</h1><p>This is the home page</p>🎯 In your route:
Section titled “🎯 In your route:”app.get('/', (req, res) => { res.render('index', { title: 'Home Page' });});The rendered result will be:
layout.ejs+index.ejscontent inside<%- body %>
4.3 ✅ Summary
Section titled “4.3 ✅ Summary”| Concept | Purpose |
|---|---|
| Partials | Reusable HTML blocks (like header.ejs) |
| Layouts | Master page template (like layout.ejs) |
express-ejs-layouts | Allows EJS to support layout injection |
<%- body %> | Placeholder where page content gets inserted |