Strings and template literals

Create and combine text, build strings with template literals, and use the string methods you will reach for every day.

  • Beginner
  • 7 min read
  • Updated 17 Oct 2026

What you will learn

  • Build strings with template literals
  • Use common string methods
  • Search, slice and clean up text
  • Compare strings for sorting with localeCompare

Before you start

Most of what a web page shows is text, so you will work with strings constantly: labels, messages, names, search terms. This lesson covers creating strings, building them with template literals, and the methods you will use most often.

Creating strings

You can write a string with double quotes, single quotes or backticks:

JavaScript
const first = "Hello";
const second = 'Hello';
const third = `Hello`;

Double and single quotes behave identically. Pick one style and use it consistently; this course uses double quotes. Backticks create template literals, which have extra powers covered below.

If your text contains the same quote you used to wrap it, either switch quote style or escape the quote with a backslash:

JavaScript
const a = "It's sunny";
const b = 'She said "hello"';
const c = "She said \"hello\"";

Other useful escape sequences are \n for a new line and \\ for a literal backslash.

Length and characters

Every string has a length property:

JavaScript
const word = "JavaScript";
console.log(word.length);
// 10

Read a single character by its index, counting from 0. The at() method also accepts negative numbers, which count from the end:

JavaScript
console.log(word[0]);
// J
console.log(word.at(-1));
// t

Strings are immutable. word[0] = "j" does nothing; to change text, you create a new string.

length counts UTF-16 code units, not visible characters. Most text gives the answer you expect, but many emoji and some accented characters made of several parts count as 2 or more. That rarely matters until you limit or truncate text, where it is worth testing with real data.

Joining strings

The + operator joins, or concatenates, strings:

JavaScript
const firstName = "Grace";
const lastName = "Hopper";
console.log(firstName + " " + lastName);
// Grace Hopper

This gets messy quickly when you mix text and values. Template literals are better.

Template literals

A template literal is wrapped in backticks. Inside it, ${...} inserts the value of any expression:

JavaScript
const name = "Grace";
const lessons = 12;

console.log(`Welcome back, ${name}. You have ${lessons} lessons left.`);
// Welcome back, Grace. You have 12 lessons left.

Any expression works inside ${}, including calculations and function calls:

JavaScript
const price = 4.5;
const quantity = 3;
console.log(`Total: £${(price * quantity).toFixed(2)}`);
// Total: £13.50

Template literals can also span several lines. The line breaks become part of the string:

JavaScript
const address = `10 High Street
Bristol
BS1 1AA`;

console.log(address);
// 10 High Street
// Bristol
// BS1 1AA

Use template literals whenever you combine text with values. They are easier to read and you cannot forget a space between pieces.

Template literals make it tempting to build HTML as a string and insert it into the page. If any part of that string comes from a person or an external source, that is a security risk. Lesson 15 shows the safe way to put text on a page.

Changing case and trimming

These methods return a new string and leave the original unchanged:

JavaScript
const input = "   Ada@Example.com  ";

console.log(input.trim());
// Ada@Example.com
console.log(input.trim().toLowerCase());
// ada@example.com
console.log("hello".toUpperCase());
// HELLO

trim() removes whitespace from both ends; trimStart() and trimEnd() remove it from one end. Trimming and lowercasing is a common first step when comparing text that people type, such as email addresses.

Notice how the calls are chained: each method returns a new string, so you can call another method on the result straight away.

Searching inside strings

JavaScript
const title = "Learn JavaScript in small steps";

console.log(title.includes("Script"));
// true
console.log(title.includes("script"));
// false
console.log(title.startsWith("Learn"));
// true
console.log(title.endsWith("steps"));
// true
console.log(title.indexOf("in"));
// 17
console.log(title.indexOf("Python"));
// -1
  • includes, startsWith and endsWith return a boolean. They are case-sensitive.
  • indexOf returns the position of the first match, or -1 if there is none.

For a case-insensitive search, lowercase both strings first:

JavaScript
const query = "SCRIPT";
console.log(title.toLowerCase().includes(query.toLowerCase()));
// true

You will use exactly this pattern to build a search box for the course dashboard later in the course.

Extracting part of a string

slice(start, end) returns the characters from start up to, but not including, end:

JavaScript
const code = "GB-2024-0042";

console.log(code.slice(0, 2));
// GB
console.log(code.slice(3, 7));
// 2024
console.log(code.slice(-4));
// 0042

Leave out end to go to the end of the string. Negative numbers count from the end. You may see substring() in older code; it does a similar job but handles negative numbers differently, so prefer slice().

Splitting and joining

split() breaks a string into an array of pieces at a separator. The array method join() does the reverse:

JavaScript
const tags = "html,css,javascript";
const tagList = tags.split(",");
console.log(tagList);
// ["html", "css", "javascript"]

console.log(tagList.join(" / "));
// html / css / javascript

Lesson 12 covers arrays.

Replacing text

JavaScript
const sentence = "I like cats. cats are great.";

console.log(sentence.replace("cats", "dogs"));
// I like dogs. cats are great.
console.log(sentence.replaceAll("cats", "dogs"));
// I like dogs. dogs are great.

replace() with a string changes only the first match. replaceAll() changes every match. Both can also take a regular expression for pattern-based replacements, which lesson 38 covers.

Padding and repeating

JavaScript
const orderNumber = "42";
console.log(orderNumber.padStart(5, "0"));
// 00042

console.log("-".repeat(10));
// ----------

padStart() and padEnd() are useful for fixed-width output such as order numbers or simple text tables.

Converting to and from strings

String() converts any value to a string. A number's toString() method does the same:

JavaScript
console.log(String(42));
// 42
console.log((3.5).toString());
// 3.5
console.log(String(null));
// null

Going the other way, from text to a number, is covered in the next lesson.

Comparing strings for sorting

The < and > operators compare strings by character code, which puts all uppercase letters before lowercase ones and handles accents poorly. To compare text in the way people expect, use localeCompare(). It returns a negative number if the first string sorts first, a positive number if it sorts second, and 0 if they are equivalent:

JavaScript
console.log("apple".localeCompare("Banana"));
// -1
console.log("Zebra" < "apple");
// true
console.log("Zebra".localeCompare("apple"));
// 1

The exact number is not guaranteed to be 1 or -1, only its sign, so always check whether the result is below or above 0. You will use localeCompare() to sort arrays of names in lesson 22.

Summary

  • Write strings with double quotes, single quotes or backticks, and use one quote style consistently.
  • Use template literals with ${} to insert values; they also allow multi-line strings.
  • Strings are immutable: methods such as trim(), toLowerCase() and replaceAll() return new strings.
  • Search with includes(), startsWith(), endsWith() and indexOf(); lowercase both sides for case-insensitive searches.
  • Extract with slice(), split into arrays with split(), and join arrays back with join().
  • Sort human-readable text with localeCompare(), not < and >.

Further reading