Regex for URL Validation in JavaScript — Patterns and When to Use the URL API Instead
URL validation shows up everywhere — signup forms asking for a portfolio link, comment fields that should reject junk input, admin panels that store webhook endpoints. Regex can catch obviously malformed input quickly, but a truly correct URL parser is harder than most developers expect. This guide gives you working regex patterns and explains when to reach for JavaScript's built-in URL constructor instead.
Anatomy of a URL
A URL has several optional and required parts that a validator needs to account for:
https://www.example.com:8080/products/shoes?color=red&size=9#reviews \____/ \_____________/ \__/ \_____________/ \_____________/ \_____/ protocol domain port path query fragment
A Practical URL Regex
This pattern covers the common cases: optional protocol, optional www, domain, optional port, and an optional path/query/fragment tail.
const urlRegex = /^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/;
urlRegex.test('https://dev-brains-ai.com'); // true
urlRegex.test('http://localhost:3000/api/users?id=5'); // false — 'localhost' has no dot+TLD
urlRegex.test('www.example.com/path?query=1#section'); // true
urlRegex.test('not a url at all'); // falseNotice localhost fails because the pattern requires a dot followed by a TLD-like segment. If your app needs to accept local/dev URLs, add an explicit alternation for localhost and IP addresses.
// Also allow localhost and IPv4 hosts with optional port
const devFriendlyUrlRegex = /^(https?:\/\/)?((www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}|localhost|(\d{1,3}\.){3}\d{1,3})(:\d{1,5})?([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/;Extracting URLs from Free Text
A common real-world use case is pulling out URLs embedded in a paragraph, chat message, or log line rather than validating a single input:
const text = 'Check the docs at https://dev-brains-ai.com/docs and also see www.example.org for more.'; const found = text.match(/(https?:\/\/[^\s]+)|(www\.[^\s]+)/g); console.log(found); // ['https://dev-brains-ai.com/docs', 'www.example.org']
Why the Built-in URL Constructor Is Often Better
JavaScript ships with a URL class that implements the WHATWG URL parsing spec — the same rules browsers use. It handles internationalized domains, percent-encoding, unusual-but-valid schemes, and edge cases that a hand-written regex will get wrong.
function isValidUrl(input) {
try {
const url = new URL(input);
return ['http:', 'https:'].includes(url.protocol);
} catch {
return false;
}
}
isValidUrl('https://dev-brains-ai.com'); // true
isValidUrl('ftp://files.example.com'); // false — protocol not in allow-list
isValidUrl('not a url'); // false — throws, caught, returns false- Use regex when you need to scan free text for URL-like substrings, or need a fast client-side hint before a full check
- Use the URL constructor when you need to actually validate a single input field and reject genuinely malformed URLs
- Combine both — regex to find candidates, URL constructor to confirm each one is well-formed
Common Pitfalls
- Forgetting the protocol is optional in user input — always normalize by prepending
https://if missing before parsing - Using an overly permissive regex like
/^https?:\/\/.+/that accepts almost anything after the protocol - Assuming a syntactically valid URL is reachable — that requires an actual HTTP request, ideally made server-side to avoid SSRF risk from unchecked user-submitted URLs
- Not trimming whitespace before validation — trailing spaces silently break most patterns
Frequently Asked Questions
A practical pattern is /^(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/, which handles protocol, www, domain, and path/query segments for most common cases.
For strict correctness, use the built-in URL constructor (new URL(string)) wrapped in a try/catch — it parses per the WHATWG URL spec and handles edge cases regex cannot. Use regex only for lightweight pattern checks like detecting URLs inside free text.
No. Regex and the URL constructor both only validate syntax/format. Confirming a URL is reachable requires an actual network request, such as a HEAD or GET call, which should be done server-side to avoid CORS and SSRF issues.