Question

How to Check if a String Contains a Substring in JavaScript

javascriptstringsubstringstring-matching

Question

In JavaScript, how can you check whether one string contains another substring?

A method such as String.contains() might seem like the obvious choice, but that method does not exist in standard JavaScript.

What is the correct and practical way to perform this check?

Example context:

const text = "Hello world";
const search = "world";

How should you test whether text contains search?

Short Answer

By the end of this page, you will understand how to check whether a string contains a substring in JavaScript, when to use includes() versus indexOf(), how case sensitivity works, and what patterns developers commonly use in real code.

Concept

In JavaScript, checking whether a string contains a substring means asking:

  • Does this larger string include this smaller piece of text?
  • If yes, return true
  • If no, return false

This is a very common operation in programming. You use it when:

  • validating user input
  • searching text
  • filtering data
  • checking file paths or URLs
  • parsing messages or logs

The modern and most readable way to do this in JavaScript is String.prototype.includes().

const text = "Hello world";
console.log(text.includes("world")); // true

Before includes() became common, developers often used indexOf().

const text = "Hello world";
console.log(text.indexOf("world") !== -1); // true

Both approaches work, but includes() is easier to read because it directly expresses the intent: checking whether the substring exists.

A key detail is that string matching is case-sensitive by default.

"Hello".includes("hello"); // false

So the concept is simple: JavaScript lets you search within strings, and the main choice is whether you want a boolean result (includes) or the position of the match (indexOf).

Mental Model

Think of a string like a sentence written on paper.

  • The full string is the whole sentence.
  • The substring is a word or phrase you are trying to spot.
  • includes() is like asking: “Can I find this word anywhere in the sentence?”
  • indexOf() is like asking: “At what character position does this word begin?”

If you only care whether it exists, use includes(). If you also care where it appears, use indexOf().

Take Quiz

Syntax and Examples

Basic syntax

Using includes()

string.includes(searchString)
string.includes(searchString, startPosition)
  • searchString: the substring to look for
  • startPosition: optional index to start searching from
  • returns true or false

Example:

const text = "JavaScript is fun";

console.log(text.includes("Script")); // true
console.log(text.includes("Python")); // false

This is the clearest way to test for a substring.

Using indexOf()

string.indexOf(searchString)
string.indexOf(searchString, startPosition)
  • returns the index of the first match
  • returns -1 if not found

Example:

const text = "JavaScript is fun";

console.log(text.indexOf("Script")); // 4
console.log(text.indexOf("Python")); // -1
console.log(text.indexOf("Script") !== -1); // true

Case-sensitive search

const text = "Hello World";

console.log(text.includes("World")); // true
console.log(text.includes("world")); // false

Case-insensitive search

A common beginner-friendly solution is to normalize both strings.

const text = "Hello World";
const search = "world";

console.log(text.toLowerCase().includes(search.toLowerCase())); // true

Checking from a specific position

const text = "banana";

console.log(text.includes("na")); // true
console.log(text.includes("na", 3)); // true
console.log(text.includes("ba", 1)); // false

The second argument tells JavaScript where to begin searching.

Step by Step Execution

Consider this example:

const text = "Hello world";
const result = text.includes("world");
console.log(result);

Step by step:

  1. text stores the string "Hello world".
  2. JavaScript evaluates text.includes("world").
  3. It scans the string looking for the exact sequence of characters w, o, r, l, d.
  4. It finds that sequence starting at index 6.
  5. Because the substring exists, includes() returns true.
  6. result now stores true.
  7. console.log(result) prints true.

Now compare with indexOf():

const text = "Hello world";
const result = text.indexOf("world");
console.log(result);

Step by step:

  1. text stores "Hello world".
  2. JavaScript evaluates text.indexOf("world").
  3. It searches for the first occurrence of "world".
  4. It finds it beginning at character index 6.
  5. The method returns 6.
  6. console.log(result) prints 6.

If the substring is missing:

console.log("Hello world".includes("cat")); // false
console.log("Hello world".indexOf("cat"));  // -1

Real World Use Cases

Checking for substrings appears in many real programs.

Search input filtering

const productName = "Wireless Mouse";
const query = "mouse";

const matches = productName.toLowerCase().includes(query.toLowerCase());

Used in search bars and product filters.

Email validation shortcuts

const email = "user@example.com";
const looksLikeEmail = email.includes("@");

This is not full validation, but it can be part of a quick check.

URL or route checks

const url = "/admin/dashboard";

if (url.includes("/admin")) {
  console.log("Admin route");
}

Useful in routing or permission logic.

Log analysis

const logLine = "ERROR: database connection failed";

if (logLine.includes("ERROR")) {
  console.log("Send alert");
}

Common in monitoring scripts.

File extension checks

const filename = "report.pdf";
console.log(filename.includes(".pdf")); // true

Often used when handling uploaded files, though endsWith() may be more precise for extensions.

Take Quiz

Real Codebase Usage

In real codebases, substring checks are often part of larger patterns.

Guard clauses

Developers often exit early when required text is missing.

function processMessage(message) {
  if (!message.includes("#")) {
    return "Missing tag";
  }

  return "Valid message";
}

This keeps functions simple and readable.

Input normalization

Case-insensitive matching is very common.

function containsKeyword(text, keyword) {
  return text.toLowerCase().includes(keyword.toLowerCase());
}

This prevents failures caused by uppercase/lowercase differences.

Filtering arrays of strings

const users = ["Alice", "Bob", "Charlie"];
const query = "li";

const results = users.filter(name =>
  name.toLowerCase().includes(query.toLowerCase())
);

console.log(results); // ["Alice", "Charlie"]

This pattern is common in search features.

Validation and error handling

function validatePath(path) {
  if (!path.includes("/")) {
    throw new Error("Invalid path format");
  }
}

Config and environment checks

const env = "development-local";

if (env.includes("local")) {
  console.log("Use local services");
}

This kind of string check appears often in scripts and setup code.

Common Mistakes

1. Trying to use contains()

JavaScript strings do not use contains().

Broken code:

const text = "Hello world";
console.log(text.contains("world"));

Use this instead:

const text = "Hello world";
console.log(text.includes("world"));

2. Forgetting that indexOf() returns 0 for matches at the start

Broken code:

const text = "hello world";

if (text.indexOf("hello")) {
  console.log("Found");
}

Why this fails:

  • indexOf("hello") returns 0
  • 0 is falsy in JavaScript
  • so the if block does not run

Correct version:

if (text.indexOf("hello") !== -1) {
  console.log("Found");
}

Or better:

if (text.includes("hello")) {
  console.log("Found");
}

3. Ignoring case sensitivity

Broken expectation:

console.log("Hello".includes("hello")); // false

Fix:

console.log("Hello".toLowerCase().includes("hello".toLowerCase())); // true

4. Using substring checks when another method is more precise

For prefixes and suffixes, use dedicated methods.

const filename = "report.pdf";

console.log(filename.includes(".pdf")); // true
console.log(filename.endsWith(".pdf")); // better for extension checks

5. Searching non-strings by mistake

If the value may not be a string, convert or validate it first.

const value = 12345;
// value.includes("23"); // error

console.log(String(value).includes("23")); // true

Comparisons

MethodReturnsBest useExample
includes()true or falseCheck whether a substring existstext.includes("cat")
indexOf()index or -1Find position of first matchtext.indexOf("cat")
startsWith()true or falseCheck whether a string begins with texttext.startsWith("Hello")
endsWith()true or falseCheck whether a string ends with texttext.endsWith(".js")
Regular expressionvariesFlexible pattern matching/cat/i.test(text)

includes() vs indexOf()

  • Use includes() when you only need yes or no.
  • Use indexOf() when you need the match position.
  • includes() is usually more readable.

includes() vs regex

  • Use includes() for simple fixed text.
  • Use regular expressions when you need patterns, such as optional characters, digit matching, or case-insensitive rules.

Example:

const text = "Order #123";
console.log(text.includes("#123")); // true
console.log(/#\d+/.test(text));     // true

The regex version is more flexible but harder to read for beginners.

Take Quiz

Cheat Sheet

Quick reference

Check if substring exists

str.includes("text")

Check from a starting index

str.includes("text", startIndex)

Older alternative

str.indexOf("text") !== -1

Case-insensitive check

str.toLowerCase().includes(search.toLowerCase())

Useful related methods

str.startsWith("text")
str.endsWith("text")

Rules to remember

  • includes() returns true or false
  • indexOf() returns a number or -1
  • string matching is case-sensitive by default
  • contains() is not the standard JavaScript string method
  • use includes() for readability when you only need a boolean

Common pattern

if (message.includes("error")) {
  console.log("Handle error");
}

FAQ

How do I check if a string contains a substring in JavaScript?

Use includes():

"Hello world".includes("world"); // true

Is there a String.contains() method in JavaScript?

No. The standard method is includes().

What is the difference between includes() and indexOf()?

  • includes() returns true or false
  • indexOf() returns the starting position or -1

Is includes() case-sensitive?

Yes.

"Hello".includes("hello"); // false

How do I do a case-insensitive contains check?

Convert both strings to the same case:

text.toLowerCase().includes(search.toLowerCase())

When should I use startsWith() or endsWith() instead?

Use them when you want to check only the beginning or end of a string, not anywhere inside it.

Can I use includes() on numbers?

Not directly. Convert the value to a string first.

String(12345).includes("23"); // true
Take Quiz

Mini Project

Description

Build a simple JavaScript text search tool that checks whether a list of messages contains a user-provided keyword. This demonstrates practical substring checking, case-insensitive matching, and filtering results from an array.

Goal

Create a function that returns all messages containing a given search term, regardless of letter case.

Requirements

  1. Store several text messages in an array.
  2. Accept a search term as a string.
  3. Return only the messages that contain the search term.
  4. Make the search case-insensitive.
  5. Print the matching results to the console.
Take Quiz

Keep learning

Related questions

View more