Lodash _.templateSettings.escape

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Template configuration

What You’ll Learn

By the end of this tutorial, you’ll understand Lodash’s escape RegExp, how it differs from safe interpolate tags, and when raw HTML output is appropriate.

01

RegExp, not fn

escape matches delimiter tags—like interpolate and evaluate.

02

Raw output tags

Default open-percent-minus tags skip HTML escaping.

03

Safe interpolate

Default value tags call _.escape automatically.

04

XSS awareness

Never pass user input through raw-output tags.

05

Trusted HTML

Use escape tags for vetted markup partials only.

06

Per-template override

Pass a custom escape RegExp in options.

What Is _.templateSettings.escape?

_.templateSettings.escape is a RegExp that marks delimiter tags for unescaped value insertion in Lodash templates. Despite the name, it does not assign an escape function—it defines which syntax produces raw HTML output (default: open-percent-minus tags).

💡
Beginner tip — naming is confusing

In Lodash, interpolate tags (open-percent-equals) are the safe, HTML-escaped path. escape tags (open-percent-minus) output raw strings. For user comments or names, always use interpolate—not escape.

Customize the escape RegExp when you need a different raw-output delimiter while keeping interpolate on another syntax (for example Mustache braces for values and ERB-minus for trusted partials).

📝 Syntax

Assign a RegExp to the global settings object (or pass it per compile):

javascript
_.templateSettings.escape = /PATTERN/g;

// Default Lodash raw-output pattern:
// /<%-([\s\S]+?)%>/g

Syntax Rules

  • Type — must be a RegExp, never a function.
  • Default tag — open-percent-minus inserts values without calling _.escape.
  • Safe default — open-percent-equals interpolate tags escape HTML via _.escape.
  • Capture group — group 1 holds the JavaScript expression whose value is inserted raw.
  • Compile time — Lodash reads the pattern when _.template() runs.
javascript
import template from "lodash/template";

// Safe: user text through interpolate (escaped)
const safeTpl = template("<p><%= obj.comment %></p>");
console.log(safeTpl({ comment: '<script>alert(1)</script>' }));
// -> "<p>&lt;script&gt;alert(1)&lt;/script&gt;</p>"

⚡ Quick Reference

Tag styleSettingHTML escaped?Use for
open-percent-equalsinterpolateYes (_.escape)User-facing text
open-percent-minusescapeNo (raw)Trusted HTML only
open-percent (no equals)evaluateN/A (logic)if/else, loops
Default escape RegExp/<%-([\s\S]+?)%>/gRaw insertBuilt-in delimiter
Per-template_.template(str, { escape: /.../g })Depends on tagOne-off syntax
Standalone escape_.escape(str)YesPre-escape in JavaScript
Default
/<%-...%>/g

Raw-output tags

Type
RegExp

Not a function

Safe path
interpolate

Escaped values

Risk
XSS

If misused on user data

🧰 Property Details

How escape fits into _.templateSettings:

escape RegExp

Pattern matching raw-output tags. Captured expressions are evaluated and concatenated into the result string without HTML entity encoding.

/<%-([\s\S]+?)%>/g
interpolate (safe) Escaped

Sibling setting for value tags. Lodash wraps output with _.escape() so < and > become entities.

<%= obj.name %>
_.escape() Utility

Separate Lodash function (not templateSettings.escape). Converts & < > " ' to entities. Used internally by interpolate tags.

_.escape(userInput)
per-compile override Optional

Pass { escape: /.../g } to _.template() without mutating global settings.

_.template(str, { escape })

Do not confuse templateSettings.escape (a delimiter RegExp) with the _.escape() utility function—they solve related but different problems.

Examples Gallery

Practical escape patterns with copy-ready code, sample output, and interactive Try It Yourself labs.

📚 Getting Started

Safe interpolated output vs raw escape tags.

Example 1 — Safe user text (interpolate)

Default value tags escape HTML—use this for comments, names, and any user-supplied string.

javascript
const malicious = '<img src=x onerror=alert(1)>';

const safeTpl = _.template("<div><%= obj.comment %></div>");
console.log(safeTpl({ comment: malicious }));
// HTML entities — script does not run as markup
Try It Yourself

How It Works

Interpolate tags compile to code that passes values through _.escape before concatenation.

Example 2 — Raw HTML (escape tag)

Escape-pattern tags insert trusted markup without encoding—never use with user input.

javascript
const trustedHtml = "<strong>Sale</strong> ends tonight!";

const rawTpl = _.template("<aside><%- obj.banner %></aside>");
console.log(rawTpl({ banner: trustedHtml }));
// -> "<aside><strong>Sale</strong> ends tonight!</aside>"
Try It Yourself

📈 Practical Patterns

Side-by-side comparison, partials, and custom delimiters.

Example 3 — Same data, two tag types

See how interpolate escapes angle brackets while escape tags preserve them.

javascript
const input = "<b>Hi</b>";
const data = { text: input };

const escaped = _.template("E: <%= obj.text %>")(data);
const raw = _.template("R: <%- obj.text %>")(data);

console.log(escaped);
// E: &lt;b&gt;Hi&lt;/b&gt;

console.log(raw);
// R: <b>Hi</b>
Try It Yourself

Example 4 — Trusted partial in a layout

Combine escaped title with a vetted HTML partial via escape tag.

javascript
const layoutTpl = _.template(
  "<article>" +
  "<h1><%= obj.title %></h1>" +
  "<%- obj.bodyHtml %>" +
  "</article>"
);

console.log(layoutTpl({
  title: 'User & Partners',
  bodyHtml: "<p>Pre-rendered CMS content.</p>"
}));

How It Works

Title uses safe interpolate; body comes from a sanitized CMS pipeline you trust—not from raw user typing.

Example 5 — Custom raw delimiter

Override the escape RegExp for one template with double-bracket raw syntax.

javascript
const tpl = _.template(
  "Note: [[ obj.note ]]",
  { escape: /\[\[([\s\S]+?)\]\]/g }
);

console.log(tpl({ note: "<em>Important</em>" }));
// -> "Note: <em>Important</em>"

🚀 Beyond the Basics

Pre-escaping in JavaScript when you cannot rely on tag choice.

Example 6 — Pre-escape with _.escape()

When data must appear inside a raw tag, escape it in JavaScript first (rare—prefer interpolate tags).

javascript
const userInput = '<script>alert(1)</script>';

const tpl = _.template("<%- obj.safeText %>");
const output = tpl({ safeText: _.escape(userInput) });

console.log(output);
// Entities printed — still prefer <%= obj.text %> instead

Prefer interpolate

In almost all cases, use interpolate tags for dynamic text and reserve escape tags for HTML you intentionally want rendered.

🧠 How escape Works

1

Load escape RegExp

_.template() reads the escape pattern from settings or options.

Config
2

Match raw-output tags

Template source is scanned for escape, interpolate, and evaluate delimiters.

Parse
3

Compile without _.escape

Escape-tag expressions concatenate directly—interpolate tags wrap with _.escape.

Compile
=

Choose tags wisely

Interpolate for user data; escape tags only for HTML you trust.

📝 Notes

  • templateSettings.escape is a RegExp, not an escape function.
  • Escape-pattern tags output raw HTML—dangerous with user input.
  • Interpolate tags call _.escape automatically—default safe path.
  • The property name is historical ERB terminology—read Lodash docs, not the label alone.
  • Use _.escape() in JavaScript when pre-processing strings outside templates.
  • Never compile templates from untrusted users regardless of tag type.

Conclusion

_.templateSettings.escape configures which delimiter inserts unescaped values into Lodash templates. For everyday dynamic text, use interpolate tags. Reserve escape-pattern tags for trusted HTML snippets you control.

Next, learn logic blocks with evaluate, then inject helpers via imports.

💡 Best Practices

✅ Do

  • Use interpolate tags for all user-facing dynamic text
  • Reserve escape tags for vetted HTML from your CMS or static partials
  • Document which fields are allowed in raw-output tags
  • Run security reviews when templates render external data
  • Use _.escape() when building strings outside _.template()

❌ Don’t

  • Assign a function to templateSettings.escape
  • Pipe user comments or names through raw-output tags
  • Assume the name “escape” means automatic HTML safety
  • Mix up templateSettings.escape and the _.escape() utility
  • Compile template source supplied by end users

Key Takeaways

Knowledge Unlocked

Five things to remember about escape

Use these points when choosing Lodash output tags.

5
Core concepts
🔒 02

Interpolate

Safe escaped path.

Security
⚠️ 03

Raw tags

Trusted HTML only.

Risk
🔧 04

_.escape()

Separate utility fn.

Tool
⚙️ 05

evaluate

Logic comes next.

Next step

❓ Frequently Asked Questions

It is a RegExp that tells _.template() which tags insert values without HTML escaping. The default pattern matches open-percent-minus tags (the ERB-style raw-output delimiter).
A RegExp, like interpolate and evaluate. Lodash uses it at compile time to find raw-output tags. Do not assign a callback function to templateSettings.escape.
Standard interpolate tags (open-percent-equals) call _.escape on output. Escape-pattern tags (open-percent-minus) output raw HTML and are unsafe for user input.
Only for trusted HTML you control—pre-sanitized markup, static partials, or server-generated snippets. Never pipe user text through raw-output tags.
interpolate tags escape HTML entities before printing. escape tags (despite the name) skip escaping and insert the value as-is into the result string.
At compile time. Set templateSettings.escape before calling _.template(). Recompile after changing the RegExp.
Did you know?

Lodash inherited ERB’s three-tag model from Ruby templates. The minus sign in the raw-output delimiter marks “do not HTML-escape this insert”—opposite of what beginners often guess from the setting name escape.

Practice escape tags in the Live Editor

See how interpolate escapes user input while escape tags preserve HTML.

Open Try It editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful