Learn by reading through in order

Strings and Template Literals

Learn JavaScript strings: the 3 quote styles, template literals, tidying whitespace and case, splitting and replacing.

Text you show on screen, input from a form, a product name that comes back from an API — a lot of the values a web app handles are strings (a value made of a sequence of characters).

This article covers building strings with the 3 quote styles and template literals, then methods for cleaning input into a displayable shape: trimming whitespace, checking whether something's contained, splitting and rejoining, and aligning digits.

Building and Cleaning Up Strings — 3 Quote Styles and Template Literals

Say you want the order confirmation screen to read "Insulated Mug x 3 / Total 3600" — the product name, quantity, and amount each live in their own variable. Assembling them into one sentence is what string building is for. Let's start with how to write a string in the first place.

A string is written wrapped in single quotes ', double quotes ", or backticks. If the same quote character you wrapped it in shows up inside, that's read as the end of the string, so to include a quote character inside, either wrap it with a different quote style or put a \ in front to cancel its special meaning.

You'll see an actual backtick in the code example coming up.

The 3 Quote Styles Compared
Single' 'Double quoteswork as-is inside'Staff "pick"'Double" "Single quoteswork as-is inside"It's here"Backticks${ } embedsa value${productName}x ${quantity}
Which quote character you can write as-is inside depends on what you wrapped the string in. Only backticks let you embed values.
const productName = "Insulated Mug";   // wrapped in double quotes
const categoryName = 'Kitchen Goods';   // wrapped in single quotes

// Escape with \ to include the same quote type you wrapped with
const notice = "Staff \"Pick\"";

// Wrap with a different quote type and no escaping is needed
const notice2 = 'Staff "Pick"';

console.log(productName.length);   // 13  the character count comes back as a number
console.log(notice);               // Staff "Pick"
console.log(notice2);              // Staff "Pick"

length, which returns the character count, is a property (information attached to a value, read by name without parentheses). Unlike a method such as toFixed from the previous article, you don't write parentheses — it's not productName.length().

Strings can be joined with +, but the more variables you add, the more the quotes and + signs pile up and get hard to read. That's what template literals are for (wrap a string in backticks, and any value written inside ${ } gets embedded in it).

Inside ${ } you can write not just a variable but an expression like unitPrice * quantity, and the calculated result gets embedded.

What a Template Literal Embeds
${productName}Replaced withits valueInsulated Mug${unitPrice * 3}Calculated first,then replaced3600A newlinemid-stringPreservedas writtenA 2-linestring
What's inside ${ } gets evaluated first, then spliced into the string. Line breaks stay exactly as written.
const productName = "Insulated Mug";
const unitPrice = 1200;
const quantity = 3;

// Joining with + mixes quotes and + together
console.log(productName + " x " + quantity + " / Total " + unitPrice * quantity);

// With ${ }, both values and expressions can be written as-is
console.log(`${productName} x ${quantity} / Total ${unitPrice * quantity}`);
// Both print: Insulated Mug x 3 / Total 3600

Cleaning Up for Display — trim / slice / toUpperCase

A name typed into a form might have stray whitespace around it, or inconsistent casing. Showing it as-is can look broken, so you clean up its shape right before displaying it.

trim drops the surrounding whitespace, toUpperCase normalizes to uppercase, and slice cuts out part of the string.

slice takes a starting position and an ending position. Positions are counted from 0, and the character at the ending position isn't included.

slice(0, 1) gives you the first character; leave off the end, as in slice(1), and you get everything from there to the end.

const rawInput = "  Yamada  ";   // value received from an input field

console.log(rawInput.trim());               // Yamada
console.log(rawInput.trim().length);        // 6
console.log(rawInput.trim().toUpperCase()); // YAMADA
console.log(rawInput.trim().slice(0, 3));   // Yam  first 3 characters

// You can chain sliced results together with +
console.log(rawInput.trim().slice(0, 1).toUpperCase() + "…");  // Y…

console.log(rawInput.length);               // 10  the original still has its whitespace

Methods Don't Change the Original String

trim and toUpperCase only return the cleaned-up result as a new string — the variable you called them on stays exactly the same. To use the result, either store it in a variable or chain it into the next method call, as in the example above.

Clean up a display name from an input field into something you can show on screen. The display name rawName and member ID memberId are already declared.

① Display the name with leading and trailing whitespace removed.

② Display that same name with only its first letter capitalized.

③ Combine the member ID and the name from ② into a single greeting. Format it as "Welcome, Hanako! (member #1042)".

(If it runs correctly, an explanation will appear.)

JavaScript / TypeScript Editor

Run code to see output

Searching Inside a String — includes / startsWith / indexOf

If an email address the user typed has no @, you'd want to reject it before saving. Or maybe you want to handle an order code differently depending on whether it starts with ORD-. Checks like these use methods that search inside a string.

includes returns true or false for whether a given string shows up anywhere, and startsWith for whether the string starts with it.

When you need the actual position, use indexOf, which returns the position, as a number, of the first match. If nothing matches, it returns -1, so it doubles as a way to check whether something's contained at all.

What Type Each String Method Returns
lengthindexOfCounts charsor positionNumbertrim / slicetoUpperCaseProduces acleaned stringNew stringincludesstartsWithChecks if itmatchesBoolean
What comes back depends on the method. Counting methods return a number, cleanup methods return a new string, and checking methods return a boolean (a value with two options: true or false).
const orderCode = "ORD-2026-0042";

console.log(orderCode.includes("2026"));    // true   contained somewhere
console.log(orderCode.startsWith("ORD-"));  // true   the start matches

console.log(orderCode.indexOf("-"));        // 3      position, counted from 0
console.log(orderCode.indexOf("SHIP"));     // -1     not found

console.log(orderCode.slice(4));            // 2026-0042  position 4 to the end

Combine the position indexOf returns with slice, and you can pull out just what comes after a separator character. Once you know where the @ is, passing slice the position right after it gets you an email address's domain part.

Check an email address typed into a signup form. The registered contact contactEmail and the string typed into the input, typedEmail, are already declared.

① Display whether typedEmail contains an @ sign.

② Display the domain part of contactEmail — everything after the @ sign.

③ Display whether contactEmail starts with sato.

JavaScript / TypeScript Editor

Run code to see output

Splitting and Rejoining — split and join

Sometimes, like a CSV row or a tag input field, a single string is packed with multiple values. Handling each item separately means splitting on a separator, and going the other way — for display — means joining them back into one. split does the splitting; join does the rejoining.

split takes the character to split on. split(",") splits at every comma, and the result comes back as an array (multiple values arranged in order and bundled into one value). join runs the other way — pass it the character to place between items, and it rejoins them into a single string.

The Round Trip Between split and join
"1042,Mug,3"a single stringsplit(",")breaks it apart1042 / Mug / 3split into 3The 3split valuesGrab position 1to pull one outMugThe same3 valuesjoin(" | ")to rejoin"1042 | Mug | 3"a single string
split breaks a string apart into an array at a separator; join puts characters between the pieces to rejoin them into a single string.
const tagLine = "Kitchen,Insulated,Gift";   // contents of a tag input field

const tags = tagLine.split(",");   // split at each comma
console.log(tags.length);          // 3   the number of pieces
console.log(tags[0]);              // Kitchen    position 0 = the first value
console.log(tags[2]);              // Gift       position 2 = the third value

console.log(tags.join(" / "));     // Kitchen / Insulated / Gift
console.log("2026-09-02".split("-").join("/"));  // 2026/09/02

Pull Split Values Out by Position

From the array split returns, pull items out one at a time by writing their position, counted from 0, in square brackets — as in tags[0]. Operations on the array itself, like adding or removing items, are covered again in the arrays article.

You've received an order's line items as a single CSV row. csvLine, a string with the member ID, product name, unit price, and quantity separated by commas, is already declared.

① Display how many fields you get after splitting on commas.

② Display just the product name from the split fields.

③ Rejoin all the fields with " | " between them and display it on one line.

JavaScript / TypeScript Editor

Run code to see output

Replacing and Padding — replaceAll and padStart

Maybe you want to strip the hyphens out of a phone number before saving it, or pad an order number to 6 digits with leading zeros for display. For "reshape a received string into a fixed format" jobs like these, use replaceAll and padStart.

replaceAll takes the string to search for and the string to replace it with. Replace with an empty string "" (a zero-length string with nothing between the quotes), and that has the same effect as removing the character.

padStart takes the target length and the character to pad with (defaults to a space if you leave it off), and adds that padding character to the front for however much length is missing. If the original string is already at least that long, nothing gets added — it's returned as-is.

What replaceAll and padStart Each Return
"090-1234-5678"replaceAll swapsevery match"09012345678""72"padStart padsfront to 6 digits"000072""1234567"Already 6+digits, no pad"1234567"
Neither one changes the original string — both return the fixed-up result as a new string.
const rawCode = "ord 2026 0042";   // order code typed with spaces

console.log(rawCode.replaceAll(" ", "-"));  // ord-2026-0042
console.log("090-1234-5678".replaceAll("-", ""));  // 09012345678

console.log("42".padStart(6, "0"));   // 000042  pads with 0 up to 6 digits
console.log("42".padStart(6));        //     42  no padding character means a space
console.log("1200".padStart(3, "0")); // 1200    already 3+ digits, so unchanged

Reshape an assigned order number and a typed-in phone number into a form you can save. The order number orderNumber and the phone number rawPhone are already declared.

① Display the order number padded to 6 digits with leading zeros.

② Display an order code that adds ORD- in front of ①'s result.

③ Display the phone number with all hyphens removed.

JavaScript / TypeScript Editor

Run code to see output
QUIZ

Knowledge Check

Answer each question one by one.

Q1With const quantity = 3;, what gets embedded where ${quantity * 1200} appears inside a template literal?

Q2What does this code display?
const rawName = " hanako ";
rawName.trim();
console.log(rawName.length);

Q3What does console.log("1234567".padStart(6, "0")); display?