JavaScript example

How to replace all occurrences of a string in JavaScript

6 min read Updated Sep 2026 Runs in an isolated runtime
Quick answer

Use replaceAll(): text.replaceAll("red", "green") swaps every match and returns a new string. Plain replace() with a string only changes the first match. For a pattern, use a regex with the g flag: text.replace(/cat/gi, "dog").

This is one of the most-asked JavaScript questions of all time, because replace() looks like it should do the job and quietly stops after one hit. Since ES2021 the answer is replaceAll(), but two traps remain: building a regex from a variable (where characters like . suddenly mean "anything"), and replacement strings that contain $, which JavaScript reads as special patterns. Every example below runs on this page — hit Run, then edit the code and run it again.

1String.prototype.replaceAll()Recommended

replaceAll(search, replacement) finds every occurrence of search and returns a new string with each one swapped. When search is a plain string it is matched literally, so there is nothing to escape. Compare it with replace(), which given a string pattern stops after the first match.

replace-all.js

Output

Output: green apple, red cherry, red plum from replace(), then green apple, green cherry, green plum twice, then the original red apple, red cherry, red plum, unchanged. JavaScript strings are immutable, so always use the return value: text = text.replaceAll(…). You will still see split().join() in older code; it gives the same result and was the usual workaround before replaceAll() arrived in ES2021 (Node 15). There is no reason to write it today.

2A regex with the g flag

A regular expression replaces every match only when it carries the g (global) flag. Without it, replace() stops after the first match, just as it does with a string. Reach for a regex when the thing you are replacing is a shape rather than fixed text, or when case shouldn't matter: add i for that.

global-regex.js

Output

Output: dog, cat and CAT (first match only), dog, dog and dog, and a b c d, where /\s+/g collapsed each run of spaces and tabs. The last line is the error people search for: TypeError: String.prototype.replaceAll called with a non-global RegExp argument. replaceAll() accepts a regex, but only a global one, so a missing g fails loudly instead of silently replacing one match. With a g regex, replace() and replaceAll() behave identically.

3Using a variable in a regex: RegExp.escape()

You can't put a variable inside /…/, so the second classic question is how to build a regex at runtime. The answer is new RegExp(string, flags). The catch: the string is read as regex syntax, so a search term containing ., *, +, ?, ( or [ matches something other than you meant. Pass it through RegExp.escape() first. It is new in ES2025 and available in Node 24+ and current Chrome, Firefox and Safari.

variable-regex.js

Output

The unescaped pattern prints vX and vX and vX.3: its . matched the 5 in v152, which was never supposed to change. Escaped, the result is the intended vX and v152 and vX.3. safe.source prints \x31\.2, which looks odd but is deliberate: RegExp.escape() also escapes a leading digit or letter, so the output can't merge with a preceding \1 backreference when you glue it into a larger pattern. On older runtimes, the hand-written escapeRegExp (from MDN) gives 1\.2 and the same result. The last line prints JavaScript, JavaScript and JavaScript, which is the reason to build a regex at all. If you only need a literal, case-sensitive replace, skip the regex and call replaceAll(term, …) with the string.

4The $& and $1 replacement-pattern gotcha

The replacement string is not literal either. Both replace() and replaceAll() scan it for special patterns: $& (the whole match), $1–$99 (capture groups), $<name> (a named group), $` and $' (the text before and after the match), and $$ (one literal $). That's handy when you mean it and a data corruption bug when the replacement is user input or a price.

dollar-patterns.js

Output

On purpose, $3/$2/$1 reorders the date to 24/09/2026 and [$&] wraps the match: ship [it]. By accident, the price $10.00 becomes Total: amount0.00, because $1 was read as "group 1" (the word amount) followed by 0.00, and $$20 comes out as Total: $20. The fix is a replacer function: its return value is never scanned for patterns, so the last two lines print Total: $10.00 and Total: $$20 exactly. Use a function whenever the replacement comes from a variable you don't control.

5Which should you use?

MethodReplacesEscapingBest for
text.replaceAll("a", "b")Every matchNoneFixed text — the default
text.replace(/a/g, "b")Every matchWritten by handPatterns, case-insensitive (gi)
new RegExp(RegExp.escape(v), "g")Every matchRegExp.escape()A variable plus flags or regex parts
text.replace("a", "b")First match onlyNoneExactly one occurrence
text.split("a").join("b")Every matchNoneLegacy code, pre-ES2021 engines

6Common variation: several replacements in one pass

Chaining replaceAll() calls works until one replacement produces text that a later call also matches. To swap several strings safely, build one regex that alternates the escaped keys, and let a replacer function look each match up. The same function form also receives the capture groups, so it can transform matches instead of just substituting them.

many-at-once.js

Output

The chain prints cat chases cat: the first call turned cat into dog, and the second turned both dogs back into cats. The single pass prints dog chases cat, because every match is replaced exactly once. The replacer's second argument is the first capture group, which gives userFirstName, and the escaped + and * keys produce 2 plus 3 times 4 instead of a SyntaxError. If one key is a prefix of another (a and ab), sort the keys longest first before joining, because the alternation takes the first branch that matches.

Frequently asked questions

Why does replace() only replace the first occurrence in JavaScript?

Because that is how String.prototype.replace is specified: with a string pattern, or a regex without the g flag, it replaces the first match and stops. "red red".replace("red", "x") gives "x red". Use replaceAll("red", "x"), or a global regex such as replace(/red/g, "x"), to replace every match.

What is the difference between replace() and replaceAll()?

With a string pattern, replace() changes the first match and replaceAll() changes all of them. With a regex, both need the g flag to replace every match, and replaceAll() throws TypeError: String.prototype.replaceAll called with a non-global RegExp argument if the flag is missing. Otherwise they behave the same: both return a new string and both interpret $ patterns in the replacement.

How do I use a variable in a regular expression in JavaScript?

Build it with the constructor: new RegExp(RegExp.escape(term), "g"). The escape step matters because new RegExp("1.2") treats the dot as "any character" and also matches "152". RegExp.escape is ES2025 (Node 24+); on older runtimes use term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"). If you only need a literal replace, skip the regex and call text.replaceAll(term, replacement).

Why do dollar signs disappear or turn into other text in my replacement?

The replacement string is scanned for special patterns: $& inserts the match, $1 a capture group, $$ a single dollar sign. So "$10.00" as a replacement for a regex with one group becomes the group text plus 0.00, and "$$20" becomes $20. Pass a function instead, text.replace(pattern, () => value), and its return value is inserted literally.

Does $1 in a replacement do anything when the pattern is a plain string?

No. A string pattern has no capture groups, so $1 is left as-is: "price".replaceAll("price", "$1") returns $1. The other patterns still apply, though. $& inserts the matched text and $$ becomes one $, so a function replacer is still the safe choice for arbitrary input.

How do I replace all occurrences case-insensitively?

Use a regex with both the g and i flags: text.replace(/cat/gi, "dog") turns "Cat, cat and CAT" into "dog, dog and dog". When the word is in a variable, build the regex with new RegExp(RegExp.escape(word), "gi"). replaceAll() with a string pattern is always case-sensitive.

Run it yourself

Open any of these in the full JavaScript editor — tweak, run, and share.

JavaScript playground