The days of wrestling with fragile regex patterns or clunky URL parsers just to handle client-side routing are finally behind us. The URLPattern API brings a native, standardized way to match URLs and extract dynamic parameters directly in the browser and in server-side JavaScript runtimes. If you have ever built a single-page application, a service worker, or any tool that needs to interpret incoming URLs, this API will save you hours of debugging and boilerplate code. It is available now across modern browsers and runtimes, and it is quickly becoming the go-to solution for routing logic that is both powerful and readable.
The URLPattern API provides a native JavaScript interface for matching URL patterns and extracting dynamic segments, query parameters, and more. It replaces fragile regex hacks with a clean, declarative syntax that works across browsers, service workers, and Node.js. By adopting URLPattern in your routing layer, you can reduce code complexity, improve readability, and build more maintainable front-end applications.
Why the URLPattern API matters for modern routing
Routing has always been one of those problems that looks simple on paper but gets messy in practice. A typical app needs to match paths like /users/42 or /products/shoes?size=10 and extract the variable parts. The traditional approaches involve hand-rolled regex, string splitting, or third-party libraries that each bring their own syntax and overhead.
The URLPattern API standardizes this process. It uses a pattern syntax that is similar to the routing syntax you might already know from Express, Rails, or other frameworks. You define a pattern like /users/:id and the API handles the rest. It can match against full URLs, pathnames, hostnames, or any other URL component. And because it is built into the platform, there is no bundle size penalty and no dependency to manage.
Understanding the URLPattern pattern syntax
The pattern syntax is designed to be intuitive. You use :name for named parameters, * for wildcards, and you can even embed full regex for complex cases. Patterns are written as strings and compiled into a URLPattern object that you can reuse across many URLs.
Here is a look at the core building blocks:
| Token | Meaning | Example |
|---|---|---|
:name |
Captures a dynamic segment | /users/:id matches /users/42, captures id = "42" |
* |
Wildcard (matches anything) | /files/* matches /files/a/b/c.txt |
{...} |
Group modifiers | /blog/:year{/}? makes the trailing slash optional |
(regex) |
Custom regex matcher | /item/(\\d+) only matches numeric segments |
? |
Makes preceding token optional | /page:page? matches /page or /page/2 |
You can combine these tokens to build patterns that fit almost any routing need.
How to create and use a URLPattern
Creating a URLPattern is straightforward. You pass a pattern string or an object with specific component patterns to the constructor. Then you call .exec() on a URL or URL string to test for a match.
Step-by-step process
-
Define your pattern as a string or an options object. For pathname matching, use the
{ pathname: "/pattern" }form. -
Create a URLPattern instance with
new URLPattern(pattern). -
Call
.exec(url)on the instance. If the URL matches, it returns an object with the matched groups. If not, it returnsnull. -
Access captured groups from the
pathnameorsearchproperty of the result. -
Reuse the same pattern across many URLs. The compiled pattern is efficient and can be cached.
A concrete example
const pattern = new URLPattern({ pathname: "/products/:category/:id" });
const result = pattern.exec("https://shop.example.com/products/electronics/99");
if (result) {
console.log(result.pathname.groups.category); // "electronics"
console.log(result.pathname.groups.id); // "99"
}
The API returns groups for each named parameter, and you can also access raw input matches if needed.
Practical patterns for everyday routing
The URLPattern API shines when you need to handle common routing scenarios without ceremony.
-
Optional segments: Use
?to make parts of the path optional. For example,/docs/:section?matches both/docsand/docs/getting-started. -
Wildcard routes: Use
*to catch everything under a prefix. This is useful for file serving or fallback routes. -
Query parameter extraction: The API can also parse query strings. A pattern like
/search?q=:queryextracts thequeryparameter from the URL’s search component. -
Hostname and port matching: You can match against subdomains or specific ports by passing patterns for
hostnameorport. -
Regex for validation: When you need to enforce a format, embed a regex group. For example,
/user/(\\d+)only matches numeric user IDs.
Expert advice: Use named parameters (
:param) whenever possible. They make your patterns self-documenting and give you clean access to captured values. Reserve regex groups for validation logic, not for general-purpose matching.
Common mistakes and how to avoid them
Even with a clean API, there are pitfalls that can trip you up. Here is a table of frequent missteps and their fixes.
| Mistake | What happens | Correct approach |
|---|---|---|
| Forgetting to escape special characters | Pattern fails or matches incorrectly | Use \\ for literal colons, slashes, or asterisks |
| Using full URL when only pathname is needed | Works but less efficient | Pass { pathname: "/pattern" } for clarity and performance |
| Assuming trailing slash is matched by default | /users won’t match /users/ |
Use /users{/}? to make the trailing slash optional |
Not checking for null result |
Causes runtime errors when accessing groups | Always test if (result) before accessing groups |
| Over-nesting with optional groups | Pattern becomes hard to read | Keep patterns flat. Break complex routes into separate patterns |
Using URLPattern in a service worker
One of the most powerful use cases for the URLPattern API is inside a service worker. You can intercept fetch events and route requests to different handlers based on the URL pattern.
self.addEventListener("fetch", (event) => {
const detailPattern = new URLPattern({ pathname: "/products/:id" });
const listPattern = new URLPattern({ pathname: "/products" });
if (detailPattern.exec(event.request.url)) {
event.respondWith(handleProductDetail(event.request));
} else if (listPattern.exec(event.request.url)) {
event.respondWith(handleProductList(event.request));
} else {
event.respondWith(fetch(event.request));
}
});
This approach replaces the old string-matching or regex-based routing with a declarative, readable alternative. It is also easier to test and maintain over time.
Performance considerations
The URLPattern API is compiled once and reused. That means you should create your pattern instances outside of hot loops or critical paths. In a service worker, for example, define your patterns at the top level so they are created when the worker starts, not on every fetch event.
Benchmarks from 2025 and 2026 show that URLPattern is competitive with hand-optimized regex for most real-world patterns. The compiled internal representation is tuned for speed, and the API avoids the overhead of repeated string parsing.
If you are building a high-throughput server-side router, you might still want a dedicated library that uses a radix trie or similar structure for extreme performance. But for the vast majority of front-end and service worker use cases, URLPattern is more than sufficient.
Integrating URLPattern with your framework
Many modern frameworks are already adopting URLPattern under the hood. If you use a meta-framework or a custom router, you can often drop in URLPattern as the matching engine.
- React Router and TanStack Router have experimental support for URLPattern.
- Service worker libraries like Workbox now offer URLPattern-based routing strategies.
- SvelteKit and Astro use URLPattern for server-side route matching.
Even if your framework does not use it directly, you can still use URLPattern in your own utility functions for tasks like link validation, redirect mapping, or dynamic route generation.
A complete routing helper
Here is a small, reusable router that uses URLPattern. It can be used in any JavaScript application.
class Router {
constructor() {
this.routes = [];
}
add(pattern, handler) {
this.routes.push({ pattern: new URLPattern({ pathname: pattern }), handler });
}
resolve(url) {
for (const route of this.routes) {
const match = route.pattern.exec(url);
if (match) {
return route.handler(match.pathname.groups);
}
}
return null;
}
}
const router = new Router();
router.add("/blog/:slug", (params) => `Show blog post: ${params.slug}`);
router.add("/about", () => "About page");
console.log(router.resolve("https://site.com/blog/hello-world"));
// "Show blog post: hello-world"
This pattern keeps your routing logic organized and testable. You can extend it with middleware, error handling, or async handlers as needed.
Where URLPattern fits in your stack
The API is not just for client-side routing. It works anywhere JavaScript runs.
- In the browser: Use it for SPA routing, link validation, or dynamic imports based on URL.
- In service workers: Route fetch events, cache strategies, and navigation preloads.
- In Node.js: The API is available in Node.js 23.8.0 and later, making it a viable option for server-side request routing.
- In edge workers: Cloudflare Workers and other edge runtimes support URLPattern natively.
If you are interested in other modern web APIs that simplify your code, check out our guide on 10 Essential Web APIs Every Developer Should Know in 2026.
Testing your patterns
Before deploying a pattern, it helps to verify it against real URLs. Most browsers now include URLPattern support in the console, so you can test interactively. You can also write simple unit tests.
const pattern = new URLPattern({ pathname: "/api/:version/:resource" });
const testUrls = [
"/api/v1/users",
"/api/v2/products/123",
"/api/v1/orders/pending",
];
testUrls.forEach((url) => {
const result = pattern.exec(`http://test.local${url}`);
console.log(url, result ? result.pathname.groups : "no match");
});
This kind of testing catches edge cases early. Pay special attention to optional segments, wildcards, and patterns with multiple consecutive slashes.
Accessibility and edge cases
When designing routes, consider that users might arrive at your site through various entry points. A pattern that is too strict might return a 404 for a valid URL.
- Always decide whether trailing slashes are significant.
- Decide how to handle URL encoding. URLPattern automatically decodes percent-encoded characters in named groups.
- Be aware that the pattern syntax treats
/as a literal delimiter unless you use a wildcard or regex.
For a deeper look at building accessible and inclusive web components, see our article on How to Build Accessible Web Components That Everyone Can Use.
The future of URLPattern
As of 2026, URLPattern is Baseline Newly Available across all major browsers. The specification is stable, and adoption in frameworks and tools continues to grow. Future enhancements may include better support for multipart patterns and more ergonomic ways to handle query parameters and hash fragments.
The API is also being integrated into non-browser environments. Node.js, Deno, and Bun all support it, making it a universal standard for JavaScript routing.
Putting it into practice today
The best way to get comfortable with URLPattern is to start using it in a small part of your project. Replace one hand-rolled regex route with a URLPattern and see how it feels. The syntax is easy to read, the API is consistent, and the results are reliable.
If you are building a new application from scratch, consider using URLPattern as your primary routing mechanism. It will keep your code clean and your dependencies light.
For more on modern front-end techniques, check out our coverage of Master Modern Frontend Frameworks for Faster Web Development.
Your next steps with URLPattern
The URLPattern API is one of those rare additions to the platform that solves a real pain point without introducing new complexity. It is well-designed, well-supported, and ready for production use. Whether you are building a service worker, a single-page application, or a server-side handler, URLPattern gives you a standard way to match URLs that is both powerful and maintainable.
Try it out in your next project. Write a few patterns. Test them against real URLs. You will likely find that you can delete a surprising amount of old routing code and replace it with something cleaner. And if you want to see how other modern web APIs can simplify your work, take a look at 10 New Web APIs That Will Simplify Your Code in 2026. The web platform keeps getting better, and URLPattern is a perfect example of why that is a good thing for developers.