EJS Escaping HTML


In EJS (Embedded JavaScript), the <%- %> syntax is used to output raw HTML without escaping it. This means that the HTML content you include using <%- %> will be rendered as HTML on the client side, allowing for the inclusion of HTML tags and formatting. This can be useful when you want to insert dynamic HTML content that should not be escaped.

How <%- %> Works

  • Escaping vs. Raw Output: By default, EJS escapes HTML special characters (like <, >, and &) to prevent XSS (Cross-Site Scripting) attacks and ensure the content is displayed as plain text. However, sometimes you may want to include raw HTML, which is where <%- %> comes in. It renders the content as HTML directly.

Basic Usage

Example:

Suppose you have a variable htmlContent that contains HTML markup and you want to include this markup in your EJS template without escaping it.

Server-Side Code (Node.js with Express):

app.get('/', (req, res) => { res.render('index', { htmlContent: '<strong>Important!</strong>' }); });

EJS Template (views/index.ejs):

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Raw HTML Example</title> </head> <body> <p>Message: <%- htmlContent %></p> </body> </html>

In this example:

  • <%- htmlContent %> renders the HTML markup <strong>Important!</strong> directly, displaying it as bold text in the browser.

When to Use <%- %>

1. Inserting Rich Content

Use <%- %> when you have content that includes HTML tags or formatting that you want to be rendered as HTML, such as:

  • User-generated content where the user might include formatting.
  • Rich text from a CMS (Content Management System).

2. Including HTML Templates

If you have HTML templates or partials that you want to include directly into your main template, you can use <%- %>. This is often used for including headers, footers, or other reusable components.

Example:

Header Partial (views/partials/header.ejs):

<header> <h1>Welcome to My Website</h1> </header>

Main Template (views/index.ejs):

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Main Page</title> </head> <body> <%- include('partials/header') %> <h2>Main Content Here</h2> </body> </html>

Here, <%- include('partials/header') %> will include the raw HTML from the header.ejs partial.

Caution

  • Security Considerations: When using <%- %>, be cautious about the content being rendered. If the content is user-generated or comes from an untrusted source, ensure it is sanitized properly to prevent XSS attacks.
  • Sanitization: Use libraries or tools to sanitize user input before including it in your templates. For example, the sanitize-html package can help clean HTML content.

Example of Sanitization:

Server-Side Code:

const sanitizeHtml = require('sanitize-html'); app.get('/', (req, res) => { const unsafeHtmlContent = '<script>alert("Hacked!")</script>'; const safeHtmlContent = sanitizeHtml(unsafeHtmlContent); res.render('index', { htmlContent: safeHtmlContent }); });

EJS Template:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sanitized HTML Example</title> </head> <body> <p>Message: <%- htmlContent %></p> </body> </html>

In this example, sanitizeHtml removes unsafe content before rendering it.

Summary

  • <%- %>: Outputs raw HTML without escaping it. Use it when you need to include HTML content directly in your templates.
  • Use Cases: Suitable for rendering rich content, including HTML partials, and when you need to maintain HTML formatting.
  • Security: Always sanitize user-generated or untrusted content to prevent security vulnerabilities like XSS attacks.