Tagged Template Literals in JavaScript
Introduction
A tag function runs before the template literal is finalized. It receives string cooked parts and expression values, then returns any value—often a formatted string or a styled DOM node. This builds on template strings and powers libraries like styled-components and i18n helpers.
Prerequisites
How Tag Functions Work
javascript
// Tag receives strings array + expression values
function upperTag(strings, ...values) {
return strings.reduce((result, str, i) => {
const val = values[i] ?? "";
return result + str + String(val).toUpperCase();
}, "");
}
const name = "ada";
const line = upperTag`Hello, ${name}!`;
console.log(line);First argument: array of literal segments (including raw in strings.raw).
Simple HTML Escaper (Concept)
javascript
// Escape < for demo safety in HTML snippets
function safeHtml(strings, ...values) {
const escape = (s) =>
String(s)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">");
return strings.reduce(
(out, str, i) => out + str + escape(values[i] ?? ""),
""
);
}
const userInput = "<script>";
const html = safeHtml`<p>Comment: ${userInput}</p>`;
console.log(html);Real apps use trusted templates or framework escaping—never roll your own security alone.
Styled Output Pattern
javascript
// Return object instead of string
function css(strings, ...values) {
const style = strings.join("") + values.join("");
return { className: "dynamic", style };
}
const color = "blue";
const rule = css`color: ${color}; font-weight: bold;`;
console.log(rule);Nested Templates
javascript
const part = "world";
const full = safeHtml`Say ${part} today`;
console.log(full);Mini Example: i18n Stub
javascript
const dict = { en: { greet: "Hello" }, es: { greet: "Hola" } };
let locale = "en";
function i18n(strings, ...values) {
const key = strings.join("").trim();
const template = dict[locale][key] ?? key;
return values.reduce(
(text, val, i) => text.replace(`{${i}}`, val),
template
);
}
locale = "es";
console.log(i18n`greet` + " " + "Ada");FAQ
Tag vs normal template?
Tag adds a function call layer for custom processing.
Can the tag return non-strings?
Yes—React-like libraries return element descriptors or arrays.
String.raw?
Built-in tag preserving backslashes in raw segments—useful for regex paths.