Relative URL Resolver (url-resolver.js)
Examine the relative path normalization utility, context-aware URL constructor mappings, and query parameter preservation.
Key File Location: ./dinou/core/url-resolver.js💡 Overview
In client-side browsers, relative URLs like ../about resolve automatically based on the active tab location. However, when rendering Server Components, validating cache lifecycles, or prefetching links on the server-side, the browser context is unavailable.
The url-resolver.js utility resolves relative paths on the server. By passing the request pathname as context, it translates relative routes into absolute system paths.
📊 Normalization Flow
The flowchart below shows how incoming paths are categorized and parsed:
⚙️ Code Walkthrough
Below is the full, complete code of url-resolver.js:
function resolveRelativeUrl(href, currentPathname) {
if (!href || typeof href !== "string") {
return "/";
}
// 1. Return immediately if it is already absolute or external
if (href.startsWith("/") || href.includes("://")) {
return href;
}
// 2. Fall back to root if no base path is provided
let base = currentPathname || "/";
// 3. Ensure base directory ends with a slash so relative pathing is correct
if (!base.endsWith("/")) {
base += "/";
}
// 4. Resolve relative URL using the standard WHATWG URL constructor
const resolved = new URL(href, "http://localhost" + base);
// 5. Re-assemble and return the path, keeping query string and hash attributes
return resolved.pathname + resolved.search + resolved.hash;
}
module.exports = { resolveRelativeUrl };⏱️ Preserving State Parameters
A common bug in relative URL parsers is dropping critical metadata like query strings (?id=1) or section hashes (#features).
Dinou solves this by resolving the full path structure via the built-in Node.js URL parser and re-assembling the return string using its key properties:
resolved.pathname: The resolved target route path (e.g./docs/routing).resolved.search: The complete unmodified query string parameters (e.g.?theme=dark).resolved.hash: The target element scroll anchor tag (e.g.#overview).