Tagged template literals in JavaScript allow you to parse template literals using a function, giving you full control over how the string is constructed. The tag function receives an array of string parts and an array of evaluated expressions, enabling advanced use cases like SQL query sanitization, internationalization (i18n), styling with libraries like Styled Components, and custom DSLs (domain-specific languages).
Key Mechanics
The tag function is called with the template literal’s string parts as the first argument (an array of strings) and the interpolated values as subsequent arguments.
Use the rest operator (
...values) to capture all interpolated values dynamically.The first argument (
strings) has one more element than the number of interpolated expressions, as it splits the template at each expression.
Example: Basic Usage
function highlight(strings, ...values) {
let result = '';
strings.forEach((str, i) => {
result += str + (values[i] || '');
});
return result;
}
const name = 'Snickers';
const age = 100;
const sentence = highlight`My dog's name is ${name} and he is ${age} years old`;
console.log(sentence); // "My dog's name is Snickers and he is 100 years old"Advanced Use Cases
SQL Injection Prevention: Tag functions can separate query structure from user input, preventing injection attacks by treating values as parameters.
JSX-like Syntax: Libraries like
jsxcan use tagged templates to render HTML-like syntax without string concatenation.Styling: Frameworks like Styled Components use tagged templates to generate CSS-in-JS with dynamic styling.
Internationalization: Tag functions can handle pluralization, gender, and locale-specific formatting.
Note: Tag functions don’t need to return strings — they can return any value, including objects or DOM elements.
Tagged template literals take the form of (strings: string[], ...values: any[]): any.
In your example,
let a = (x) => console.log(x);
a`1234`; // prints "Array [ "1234" ]"
x has the type string[], which is an array of all non-interpolated strings (basically anything that's not inside ${}). Because there are no interpolations, the array contains one element (the string "1234"). This is what is passed as the first argument to your function a.
Only template literals can be "tagged" with a function identifier, which is why you've noticed that it doesn't work with single or double-quoted strings, only backticks. I presume it would throw a syntax error if you tried to do it with a regular string, though I haven't tested that.
If you wanted to interpolate a value, you'd do so by receiving the value in the function (which is used as the tag) by adding additional parameters. Note that it is not a single parameter that is an array, but rather separate parameters. You can, of course, create an array from them by using the spread operator (...), as indicated in the function signature above. As in the (modified) example provided by MDN,
const person = 'Mike';
const age = 28;
function tag(strings, person, age) {
const str0 = strings[0]; // "That "
const str1 = strings[1]; // " is a "
// There is technically a string after
// the final expression (in our example),
// but it is empty (""), so disregard.
// const str2 = strings[2];
const age_description = age > 99 ? 'centenarian' : 'youngster';
return [str0, name, str1, ageDescription].join('');
}
const output = tag`That ${person} is a ${age}`;
console.log(output); // "That Mike is a youngster"
Note that as indicated in the comments, there is always a leading and trailing string, even if it happens to be empty. As such, if you began a template literal with an interpolation, strings[0] would be an empty string. In the same manner, ending with an interpolation leaves a trailing empty string, though this isn't as notable (a leading interpolation shifts all indexes by one, a trailing doesn't affect them).
How do tagged template literals work in JavaScript? - Stack Overflow
[RFC] Support for tagged template literals - Development - ReScript Forum
Angular 20: Nuovi Tagged Template Literals nelle Espressioni ...
How to Use Tagged Templates?
Videos
I see under Template Literals that it's possible to submit a function in front of the literal. Why would you do this, rather than write a function that returns the string you need?
I've come up with two possibilities. One, it might allow you to write things to the DOM in a way similar to React. Second, I saw a YouTube video on declarative programming.
Are tagged template literals used for those purposes? Are there other reasons to use them?
TIA!