Node doesn’t have a browser location object — the path comes from the incoming request. Here’s how to read it cleanly with the WHATWG URL API, from a raw http server, and in Express, plus how to separate the path from the query string.
In a plain Node server, the request gives you req.url — but that’s the path and query together (e.g. /search?q=hello). Parse it with the URL class to split them:
const http = require('node:http');
http.createServer((req, res) => {
// req.url is path + query, e.g. "/search?q=hello"
const url = new URL(req.url, `http://${req.headers.host}`);
url.pathname; // "/search" ← the path
url.searchParams.get('q'); // "hello" ← a query value
res.end(url.pathname);
}).listen(3000);
The second argument to new URL() is a base — required because req.url is relative (it has no scheme or host). Building it from req.headers.host gives the URL object enough to parse.
Express parses the request for you. req.path is the path without the query string; req.query is the parsed query object:
app.get('*', (req, res) => {
req.path; // "/search" (no query string)
req.originalUrl; // "/search?q=hello" (full, as received)
req.query.q; // "hello" (parsed query object)
res.send(req.path);
});
| Express property | Example value |
|---|---|
req.path | /search |
req.originalUrl | /search?q=hello |
req.query | { q: "hello" } |
req.hostname | example.com |
A path can contain percent-encoded characters (e.g. /caf%C3%A9). url.pathname gives you the raw, still-encoded path; decode a segment with decodeURIComponent when you need the readable value:
const url = new URL('/caf%C3%A9/menu', 'http://x');
url.pathname; // "/caf%C3%A9/menu" (raw)
decodeURIComponent(url.pathname); // "/café/menu" (readable)
Don’t decode the whole path and then route on it — a decoded %2F becomes a real / and can change the path structure. Decode individual segments, after routing.
Want to inspect a URL’s parts without writing code? Paste it into the URL parser to see the path, query, and fragment separated and decoded.
Written and maintained by the urlencodedecode.com team. Every technical claim on this page is verified against primary sources — the RFCs (3986, 3629, 4648, 7578), the WHATWG URL Standard, and official vendor or language documentation — rather than second-hand summaries. When a source contradicts a common assumption, we follow the source and note the discrepancy. Corrections: contactus@urlencodedecode.com.
Parse the request URL with the WHATWG URL class: new URL(req.url, `http://${req.headers.host}`).pathname gives the path without the query string. In Express, req.path gives the path directly.
req.originalUrl is the full path plus query as received (/search?q=hello). req.path is just the path (/search). req.url can be modified by middleware, while req.originalUrl stays as originally received.
Because req.url is relative — it has no scheme or host, just /path?query. The URL constructor needs an absolute base to parse a relative reference, so you supply one built from req.headers.host.
Parse with new URL(): .pathname is the path and .searchParams holds the query parameters. In Express, req.path is the path and req.query is the parsed query object.
No. Decoding the whole path first turns an encoded %2F into a real slash and can change the path structure. Route on the raw pathname, then decode individual segments with decodeURIComponent when you need the readable value.