Question
How to Check if a String Contains a Substring in JavaScript
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().
Syntax and Examples
Basic syntax
Using includes()
string.includes(searchString)
string.includes(searchString, startPosition)
searchString: the substring to look forstartPosition: optional index to start searching from- returns
trueorfalse
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
-1if 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:
textstores the string"Hello world".- JavaScript evaluates
text.includes("world"). - It scans the string looking for the exact sequence of characters
w,o,r,l,d. - It finds that sequence starting at index
6. - Because the substring exists,
includes()returnstrue. resultnow storestrue.console.log(result)printstrue.
Now compare with indexOf():
const text = "Hello world";
const result = text.indexOf("world");
console.log(result);
Step by step:
textstores"Hello world".- JavaScript evaluates
text.indexOf("world"). - It searches for the first occurrence of
"world". - It finds it beginning at character index
6. - The method returns
6. console.log(result)prints6.
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.
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")returns00is falsy in JavaScript- so the
ifblock 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
| Method | Returns | Best use | Example |
|---|---|---|---|
includes() | true or false | Check whether a substring exists | text.includes("cat") |
indexOf() | index or -1 | Find position of first match | text.indexOf("cat") |
startsWith() | true or false | Check whether a string begins with text | text.startsWith("Hello") |
endsWith() | true or false | Check whether a string ends with text | text.endsWith(".js") |
| Regular expression | varies | Flexible 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.
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()returnstrueorfalseindexOf()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()returnstrueorfalseindexOf()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
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
- Store several text messages in an array.
- Accept a search term as a string.
- Return only the messages that contain the search term.
- Make the search case-insensitive.
- Print the matching results to the console.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.