Mastering EJS: Building Dynamic Web Applications with Embedded JavaScript
A Comprehensive Guide to Setup, Syntax, and Building an Example Application with EJS
Introduction
Dynamic and interactive web applications have become essential in modern development. EJS (Embedded JavaScript) is a powerful templating language that bridges the gap between server-side data processing and rendering dynamic HTML. Its simplicity, flexibility, and seamless integration with Node.js make it a go-to tool for building server-rendered applications.
This guide covers everything you need to know about EJS, including its features, syntax, setup, and implementation, along with a practical example application.
What is EJS?
EJS (Embedded JavaScript) is a templating engine that enables developers to:
Embed JavaScript logic directly within HTML templates.
Dynamically render server-side data on the client.
Create modular, reusable components for streamlined development.
EJS is lightweight, easy to learn, and ideal for applications requiring server-side rendering with Node.js.
Key Features of EJS
Dynamic HTML Rendering: Generate dynamic web pages with ease by embedding JavaScript within your templates.
Simple Syntax: Use intuitive tags like
<%= %>
to output data or<% %>
for inline JavaScript logic.Reusable Templates: Modularize your views using includes and layouts for consistent design.
Seamless Integration: Works out-of-the-box with Node.js frameworks like Express.
Performance: Minimal overhead ensures fast rendering of dynamic content.
How to Set Up EJS
Before diving into examples, let’s set up EJS in a Node.js project.
Prerequisites
Ensure you have Node.js and npm installed. If not, download and install them from Node.js.
Installation
Initialize a new Node.js project and install EJS:
npm init -y
npm install ejs
Configuring EJS with Express
Step 1: Setting Up Express
Create a basic Express server and configure EJS as the view engine:
import express from "express";
const app = express();
// Set EJS as the view engine
app.set("view engine", "ejs");
// Define the views directory
app.set("views", "views");
// Sample route
app.get("/", (req, res) => {
res.render("index", { title: "Welcome to EJS!", message: "Hello, World!" });
});
// Start the server
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
This setup allows Express to locate .ejs
files in the views
folder and render them dynamically.
Folder Structure
Your project should follow this structure:
/project
/views
index.ejs
server.js
package.json
EJS Syntax and Examples
EJS offers a simple and intuitive syntax for embedding logic and data into HTML templates.
1. Outputting Data
Escaped Output: Safely outputs HTML-escaped data.
<%= data %>
Example:
<h1>Welcome, <%= username %>!</h1>
Output:
Welcome, John!
Unescaped Output: Outputs raw HTML (use cautiously to avoid XSS vulnerabilities).
<%- htmlContent %>
2. JavaScript Logic
EJS allows inline JavaScript logic:
Conditionals:
<% if (isLoggedIn) { %> <p>You are logged in.</p> <% } else { %> <p>Please log in.</p> <% } %>
Loops:
<ul> <% items.forEach(item => { %> <li><%= item %></li> <% }); %> </ul>
3. Including Templates
Reuse components by including partials:
<%- include("partials/header") %>
<h1>Main Content</h1>
<%- include("partials/footer") %>
Building an Example Application
Let’s create a simple secrets-sharing app with the given code snippets.
Application Overview
Functionality:
Users can register, log in, and view a "secret" page.
Templates dynamically render data and share common layouts.
Folder Structure:
/project /views /partials header.ejs footer.ejs home.ejs login.ejs register.ejs secrets.ejs server.js
Code Implementation
1. Home Page Template (home.ejs
)
<%- include('partials/header') %>
<div class="jumbotron centered">
<div class="container">
<h1 class="display-3">Secrets</h1>
<p class="lead">Don't keep your secrets, share them anonymously!</p>
<a class="btn btn-light btn-lg" href="/register">Register</a>
<a class="btn btn-dark btn-lg" href="/login">Login</a>
</div>
</div>
<%- include('partials/footer') %>
2. Login Page (login.ejs
)
<%- include('partials/header') %>
<div class="container mt-5">
<h1>Login</h1>
<form action="/login" method="POST">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-dark">Login</button>
</form>
</div>
<%- include('partials/footer') %>
3. Register Page (register.ejs
)
<%- include('partials/header') %>
<div class="container mt-5">
<h1>Register</h1>
<form action="/register" method="POST">
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" name="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-dark">Register</button>
</form>
</div>
<%- include('partials/footer') %>
4. Secrets Page (secrets.ejs
)
<%- include('partials/header') %>
<div class="jumbotron text-center">
<h1>You've Discovered My Secret!</h1>
<p class="secret-text">This is a hidden message.</p>
<a class="btn btn-light btn-lg" href="/logout">Log Out</a>
</div>
<%- include('partials/footer') %>
5. Header and Footer Templates
header.ejs
:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Secrets</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"> </head> <body>
footer.ejs
:</body> </html>
Server Logic
import express from "express";
const app = express();
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(express.urlencoded({ extended: true }));
// Routes
app.get("/", (req, res) => res.render("home"));
app.get("/login", (req, res) => res.render("login"));
app.get("/register", (req, res) => res.render("register"));
app.get("/secrets", (req, res) => res.render("secrets"));
// Start Server
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
Conclusion
EJS empowers developers to build robust, dynamic web applications using familiar JavaScript syntax. By integrating seamlessly with Node.js and Express, EJS simplifies server-side rendering while promoting code reuse and maintainability.
Try implementing the example application to explore the versatility of EJS in action!