Skip to content

Pocket Dex: The Service Manual

SymbolNameFunctionExample
<% %>ScriptletExecutes JavaScript logic without output.<% if (user) { %>
<%= %>Escaped OutputRenders a value to the template; escapes HTML characters.<%= user.name %>
<%- %>Unescaped OutputRenders raw HTML value; No sanitation.<%- body %>
<%# %>CommentServer-side comment; stripped before rendering.<%# TODO: Fix this %>
include()IncludeEmbeds another view file; must be used with unescaped tag.<%- include('header') %>

Essential settings for the Express application instance.

  • Install EJS: npm install ejs
  • Install Layouts: npm install express-ejs-layouts
  • Set View Engine: app.set("view engine", "ejs")
  • Set Views Path: app.set("views", path.join(__dirname, "views"))
  • Enable Layouts: app.use(expressLayouts)
  • Set Default Layout: app.set("layout", "./layouts/master")
  • Render View: res.render("view-name", { data: value })
HazardCauseFix
XSS InjectionUsing <%- %> with untrusted user input.Always use <%= %> for user-generated content.
Broken PathsUsing relative paths like ./views.ALWAYS use path.join(__dirname, 'views').
Layouts IgnoredMiddleware initialized after routes.Move app.use(expressLayouts) above route definitions.
Missing VarsAccessing a variable not passed in locals.Ensure all expected variables are in the render payload.
Silent FailuresLogic errors inside <% %> blocks.Check server console; scriptlets don’t print errors to UI.
  • Locals Unpacking: Keys in the res.render object become top-level variables in the view.
  • Partial Scope: Partials automatically inherit access to all variables available in the parent view.
  • Layout Injection: The body variable in a layout file is a reserved keyword containing the rendered view string.
  • Route Override: Pass layout: "./other_layout" in res.render options to swap the layout frame for a specific response.
  • Extension Lookup: Express automatically appends .ejs when the view engine is set, so extensions in res.render are optional.