Express URL Rewrite Middleware
express-urlrewrite is an Express.js middleware designed for flexible URL rewriting within an application. It allows developers to transform incoming request URLs based on regular expressions, route parameters, or wildcard patterns, without performing HTTP redirects. This is crucial for internal routing, path normalization, or creating cleaner URLs. The library is currently at version 2.0.3 and appears to be in a maintenance phase, with the last publish over two years ago. Its key differentiators include robust support for dynamic rewriting using named or numeric route parameters, wildcards (`*`), and the ability to modify query strings. A notable feature is its capacity to act as route-specific middleware, passing control to the *next matching route* in the Express router rather than the general next middleware in the stack, offering fine-grained control over the request flow.
Common errors
-
TypeError: app.use() requires a middleware function but got a Object
cause Attempting to use `express-urlrewrite` without correctly importing or calling the `rewrite` function, or passing an invalid argument to `app.use()`.fixEnsure `express-urlrewrite` is correctly imported and `rewrite` is called with its arguments: `app.use(rewrite('/pattern', '/replacement'))`. For ESM, use `import rewrite from 'express-urlrewrite';`. -
My URL rewrite is not working, the browser still has the same link / Express redirect wrong url
cause This middleware performs an *internal* rewrite of `req.url`, not an HTTP redirect. The browser's address bar will not change.fixThis is the intended behavior of `express-urlrewrite`. If you require a browser-visible redirect (changing the URL in the address bar), use Express's `res.redirect()` method instead. For example: `app.get('/old-path', (req, res) => res.redirect('/new-path'));`. -
Regular expression for rewrite does not match expected URLs.
cause Special characters in the URL path, such as `.` (dot) or `?` (question mark), are not properly escaped in the regular expression pattern passed to `rewrite`.fixEscape regex special characters. For example, to match a literal question mark in the URL's path, use `\\?`. To match a literal dot, use `\\.` in your pattern. Test your regex thoroughly.
Warnings
- gotcha When using regular expressions for URL patterns, the query string delimiter `?` must be escaped with a double backslash (`\\?`) if you intend to match it literally. Otherwise, `?` acts as a quantifier in regex, which can lead to unexpected matching behavior.
- gotcha When `rewrite` is used as a route-specific middleware (e.g., `app.get('/route', rewrite(...))`), it passes control to the *next matching route* in the Express application, not merely the next middleware in the current stack. This differs from standard middleware behavior and is a powerful, but potentially confusing, feature introduced in v1.2.
- gotcha Prior to version 1.1, rewriting a URL to include a new query string (e.g., `/path` to `/anotherpath?param=some`) would not update `req.query`. This meant `req.query.param` would remain undefined.
Install
-
npm install express-urlrewrite -
yarn add express-urlrewrite -
pnpm add express-urlrewrite
Imports
- rewrite
const rewrite = require('express-urlrewrite');import rewrite from 'express-urlrewrite';
- RewriteFunction
import type { RequestHandler } from 'express'; import type RewriteFunction from 'express-urlrewrite'; - Using with app.use
app.use(rewrite('/oldpath', '/newpath'));
Quickstart
import express from 'express';
import rewrite from 'express-urlrewrite';
const app = express();
const PORT = process.env.PORT || 3000;
// Debugging can be enabled via environment variable: DEBUG=express-urlrewrite
// Rewrite /item/123 to /product/123
app.use(rewrite('/item/:id', '/product/:id'));
// Rewrite /legacy-js/vendor/jquery.js to /assets/js/vendor/jquery.js
// Uses wildcard to capture multiple segments
app.use(rewrite('/legacy-js/*', '/assets/js/$1'));
// Rewrite URLs with query string parameter directly into path segment
// Note: The '?' must be escaped in the regular expression
app.use(rewrite('/search\?q=:query', '/results/:query'));
app.get('/product/:id', (req, res) => {
res.send(`Displaying product ID: ${req.params.id}`);
});
app.get('/assets/js/:path(*)', (req, res) => {
res.send(`Serving static asset: ${req.params.path}`);
});
app.get('/results/:query', (req, res) => {
res.send(`Search results for: ${req.params.query}`);
});
app.get('/', (req, res) => {
res.send('Welcome! Try /item/456, /legacy-js/vendor/library.js, or /search?q=test');
});
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Try accessing:');
console.log(`- http://localhost:${PORT}/item/456`);
console.log(`- http://localhost:${PORT}/legacy-js/vendor/library.js`);
console.log(`- http://localhost:${PORT}/search?q=example`);
});