In frontend development or Node.js server-side rendering, templating engines are powerful tools for dynamic HTML generation.
Among them, EJS (Embedded JavaScript Templates) stands out. Let’s explore its features, core syntax, and practical use cases!


πŸ”₯ Key Features of EJS

  • βœ… HTML-like Syntax: Embeds JavaScript directly into HTMLβ€”easy to learn!
  • βœ… Flexibility: Supports conditionals, loops, and partial templates.
  • βœ… Dual Compatibility: Works in browsers and Node.js environments.
  • βœ… Lightweight: Blazing-fast performance with minimal setup.

πŸ“œ Basic Syntax Crash Course

1️⃣ Output Escaped Variables

<h1><%= title %></h1>  

<%= %> escapes HTML to prevent XSS attacks.

2️⃣ Execute JavaScript Logic

<% if (user) { %>  
  <p>Welcome, <%= user.name %>! πŸ‘‹</p>  
<% } %>  

<% %> runs JS code without outputting content.

3️⃣ Unescaped Output (Caution! ⚠️)

<%- include('header') %>  

<%- %> renders raw HTMLβ€”ideal for partials but risky with user input.


βš™οΈ Installation

npm install ejs  

πŸ›  Basic Usage (Node.js + Express)

1️⃣ Template File (views/index.ejs)

<!DOCTYPE html>  
<html>  
<head>  
  <title><%= pageTitle %></title>  
</head>  
<body>  
  <%- include('partials/navbar') %>  
  <h1>Welcome to <%= siteName %>! πŸŽ‰</h1>  
</body>  
</html>  

2️⃣ Express Configuration

const express = require('express');  
const app = express();  

// Set EJS as the template engine  
app.set('view engine', 'ejs');  
app.set('views', './views');  

// Render the template with data  
app.get('/', (req, res) => {  
  res.render('index', {  
    pageTitle: 'Home',  
    siteName: 'My Awesome Site πŸš€'  
  });  
});  

πŸ’» Practical Example: Blog Post Listing

🎯 Implementation Flow

  1. Prepare Data: Create an array of blog posts in Node.js.
  2. Pass Data: Use res.render() to send data to the template.
  3. Render Dynamically: Loop through posts with forEach in EJS.

πŸ–₯️ Template (views/articles.ejs)

<% articles.forEach(article => { %>  
  <div class="article">  
    <h2><%= article.title %></h2>  
    <p><%- article.content.substring(0, 100) %>... πŸ”</p>  
    <small>πŸ“… Posted: <%= article.date.toLocaleDateString() %></small>  
  </div>  
<% }) %>  

πŸ”§ Server-Side Code (Express)

app.get('/articles', (req, res) => {  
  const articles = [  
    {  
      title: 'Getting Started with EJS',  
      content: '<p>EJS simplifies HTML templating! 🌟</p>',  
      date: new Date('2024-03-01')  
    },  
    {  
      title: 'Node.js Fundamentals',  
      content: '<ul><li>Event Loop</li><li>Async Patterns</li></ul>',  
      date: new Date('2024-03-05')  
    }  
  ];  

  res.render('articles', { articles });  
});  

🎨 Generated HTML Preview

<div class="article">  
  <h2>Getting Started with EJS</h2>  
  <p><p>EJS simplifies HTML templating! 🌟</p>... πŸ”</p>  
  <small>πŸ“… Posted: 3/1/2024</small>  
</div>  

⭐ Top EJS Features You’ll Love

  1. Partials Reuse:

    <%- include('components/footer') %>  
    
  2. Custom Delimiters:

    ejs.delimiter = '#'; // Change <% to #%  
    
  3. Caching for Production:

    app.set('view cache', true); // Turbocharge your app! ⚑  
    

⚠️ Critical Best Practices

  1. XSS Protection: Never use <%- %> with untrusted user input.
  2. Logic Separation: Keep complex calculations in controllers, not templates.
  3. Performance: Implement pagination for large datasets (>100 items).

πŸ†š EJS vs. Other Engines

FeatureEJSPugHandlebars
SyntaxHTML-styleIndentationMustache
Learning CurveLow 😊Moderate 😐Moderate 😐
Partialsβœ…βœ…βœ…
Async SupportβŒβŒβœ…

🏁 Conclusion

EJS shines with its HTML-first approach and minimal learning curve! 🎯

  • Perfect for small to medium projects πŸ› οΈ
  • Reuse existing HTML/CSS assets ♻️
  • JavaScript logic feels natural 🧠

Stay tuned for our advanced guide on layouts, custom helpers, and EJS optimizations! πŸ”₯