URI.js is a Javascript library for working with URLs.
—
Convert between relative and absolute URIs, resolve against base URIs, and compare URI equality with proper normalization.
Methods for converting between relative and absolute URIs using base URI resolution.
/**
* Convert relative URI to absolute using base URI
* @param base - Base URI for resolution (string or URI instance)
* @returns New URI instance with absolute URI
*/
absoluteTo(base: string | URI): URI;
/**
* Convert absolute URI to relative using base URI
* @param base - Base URI for relativization (string or URI instance)
* @returns New URI instance with relative URI
*/
relativeTo(base: string | URI): URI;Usage Examples:
// Absolute resolution
const relative = new URI('../images/logo.png');
const base = 'http://example.com/docs/guide/';
const absolute = relative.absoluteTo(base);
console.log(absolute.toString()); // 'http://example.com/docs/images/logo.png'
// Complex relative resolution
const complex = new URI('../../api/v2/users?page=1');
const complexBase = 'http://api.example.com/docs/v1/guide/intro.html';
const resolved = complex.absoluteTo(complexBase);
console.log(resolved.toString()); // 'http://api.example.com/api/v2/users?page=1'
// Relative conversion
const abs = new URI('http://example.com/docs/images/logo.png');
const baseForRel = 'http://example.com/docs/guide/';
const rel = abs.relativeTo(baseForRel);
console.log(rel.toString()); // '../images/logo.png'
// Same directory
const sameDir = new URI('http://example.com/docs/guide/page.html');
const sameDirBase = 'http://example.com/docs/guide/intro.html';
const sameDirRel = sameDir.relativeTo(sameDirBase);
console.log(sameDirRel.toString()); // 'page.html'Methods for comparing URI equality with proper normalization.
/**
* Compare URIs for equality
* @param uri - URI to compare against (string or URI instance)
* @returns Boolean indicating equality
*/
equals(uri: string | URI): boolean;Usage Examples:
// Basic equality
const uri1 = new URI('http://example.com/path');
const uri2 = new URI('http://example.com/path');
console.log(uri1.equals(uri2)); // true
// Case insensitive comparison
const uri3 = new URI('HTTP://EXAMPLE.COM/path');
const uri4 = new URI('http://example.com/path');
console.log(uri3.equals(uri4)); // true (after normalization)
// Default port comparison
const uri5 = new URI('http://example.com:80/path');
const uri6 = new URI('http://example.com/path');
console.log(uri5.equals(uri6)); // true (port 80 is default for http)
// Path normalization comparison
const uri7 = new URI('http://example.com/path/../docs/./file.html');
const uri8 = new URI('http://example.com/docs/file.html');
console.log(uri7.equals(uri8)); // true (after path normalization)
// Query parameter order
const uri9 = new URI('http://example.com/search?a=1&b=2');
const uri10 = new URI('http://example.com/search?b=2&a=1');
console.log(uri9.equals(uri10)); // false (query order matters)
// Fragment comparison
const uri11 = new URI('http://example.com/page#section1');
const uri12 = new URI('http://example.com/page#section2');
console.log(uri11.equals(uri12)); // falseComplex resolution patterns and edge cases.
Usage Examples:
// Protocol-relative URLs
const protocolRel = new URI('//cdn.example.com/assets/script.js');
const httpsBase = 'https://example.com/page';
const resolvedHttps = protocolRel.absoluteTo(httpsBase);
console.log(resolvedHttps.toString()); // 'https://cdn.example.com/assets/script.js'
// Root-relative URLs
const rootRel = new URI('/api/users');
const deepBase = 'http://example.com/app/admin/dashboard.html';
const rootResolved = rootRel.absoluteTo(deepBase);
console.log(rootResolved.toString()); // 'http://example.com/api/users'
// Query and fragment preservation
const relWithQuery = new URI('../search?q=test#results');
const baseWithQuery = 'http://example.com/docs/guide?version=1.0#intro';
const resolvedWithQuery = relWithQuery.absoluteTo(baseWithQuery);
console.log(resolvedWithQuery.toString()); // 'http://example.com/search?q=test#results'
// Cross-domain resolution
const crossDomain = new URI('http://other.com/page');
const localBase = 'http://example.com/current';
const crossResolved = crossDomain.absoluteTo(localBase);
console.log(crossResolved.toString()); // 'http://other.com/page' (unchanged)
// Edge case: empty relative
const empty = new URI('');
const emptyBase = 'http://example.com/path/to/page.html';
const emptyResolved = empty.absoluteTo(emptyBase);
console.log(emptyResolved.toString()); // 'http://example.com/path/to/page.html'Calculating relative paths between different URIs.
Usage Examples:
// Different directories
const from = new URI('http://example.com/docs/api/reference.html');
const to = new URI('http://example.com/assets/images/logo.png');
const relative = to.relativeTo(from);
console.log(relative.toString()); // '../../assets/images/logo.png'
// Same directory different files
const sameDir1 = new URI('http://example.com/docs/intro.html');
const sameDir2 = new URI('http://example.com/docs/advanced.html');
const sameDirRel = sameDir2.relativeTo(sameDir1);
console.log(sameDirRel.toString()); // 'advanced.html'
// Subdirectory to parent
const child = new URI('http://example.com/docs/api/endpoints/users.html');
const parent = new URI('http://example.com/docs/index.html');
const upRel = parent.relativeTo(child);
console.log(upRel.toString()); // '../../index.html'
// Different hosts (cannot be relative)
const host1 = new URI('http://example.com/page');
const host2 = new URI('http://other.com/page');
const crossHostRel = host2.relativeTo(host1);
console.log(crossHostRel.toString()); // 'http://other.com/page' (absolute)
// With query parameters
const withQuery1 = new URI('http://example.com/search?q=old');
const withQuery2 = new URI('http://example.com/results?q=new');
const queryRel = withQuery2.relativeTo(withQuery1);
console.log(queryRel.toString()); // 'results?q=new'Extracting base URIs and working with URI hierarchies.
Usage Examples:
// Extract directory base
const fileUri = new URI('http://example.com/docs/guide/intro.html');
const dirBase = fileUri.clone().filename('').toString();
console.log(dirBase); // 'http://example.com/docs/guide/'
// Extract domain base
const domainBase = fileUri.clone().pathname('').query('').fragment('').toString();
console.log(domainBase); // 'http://example.com'
// Working with URI hierarchies
const deepUri = new URI('http://api.example.com/v1/users/123/posts/456?details=true');
// Get parent resource
const segments = deepUri.segment();
segments.pop(); // Remove last segment
const parentResource = deepUri.clone().segment(segments).query('').toString();
console.log(parentResource); // 'http://api.example.com/v1/users/123/posts'
// Get collection URI
const collectionSegments = deepUri.segment();
collectionSegments.splice(-1, 1); // Remove resource ID
const collectionUri = deepUri.clone().segment(collectionSegments).query('').toString();
console.log(collectionUri); // 'http://api.example.com/v1/users/123/posts'Install with Tessl CLI
npx tessl i tessl/npm-urijs