What are tagged template literals?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A tagged template lets a function intercept a template literal before it becomes a string. You put the function name directly in front of the backticks, and it receives the static text and the interpolated values as separate arguments.
function tag(strings, ...values) {
console.log(strings); // ["Hello ", "! You are ", " years old"]
console.log(values); // ["Mai", 30]
return "anything you like";
}
tag`Hello ${"Mai"}! You are ${30} years old`;
The key point is that strings is always one element longer than values, and the two alternate. Because the tag controls the output, it can return an object, a number, anything — not just a string.
Why the separation matters
The static parts are written by you; the interpolated values may come from users. Keeping them apart is what makes safe escaping possible:
function safe(strings, ...values) {
return strings.reduce(
(out, str, i) => out + str + (i < values.length ? escapeHtml(values[i]) : ""),
""
);
}
const html = safe`<p>${userInput}</p>`; // userInput escaped, markup is not
This is exactly how libraries build SQL statements with parameter binding rather than string concatenation — the same idea that prevents injection.
Where you have seen it
styled-components (styled.div...), `graphql-tag` (`gql`...), and i18n libraries all use tagged templates. String.raw is a built-in tag that returns the text with escape sequences untouched:
String.raw`C:\new\table`; // "C:\new\table", not a newline and a tab
Write your own tag when you need to validate, escape or transform interpolated values consistently — it moves that logic to one place instead of every call site.
