I still can’t believe javascript - the f**ing backbone-language of the web - doesn’t offer an API for mutating URLs. Browsers (Firefox) don’t expose the Location object (the structure behind window.location). Yes, one could think of decomposed IDL attributes as a native URL management library. But it relies on the DOM element <a>, it’s slow and doesn’t offer any convenience at all.
How about a nice, clean and simple API for mutating URIs:
var url = new URI("http://example.org/foo?bar=baz");
url.addQuery("foo", "bar");
URI.js (without plugins) has a gzipped weight of about 7KB - if you include all extensions you end up at about 13KB. So unless you need second level domain support and use URI templates, we suggest you don’t include them in your build. If you don’t need a full featured URI mangler, it may be worth looking into the much smaller parser-only alternatives listed below.
# using bower
bower install uri.js
# using Jam
jam install URIjs
# using npm
npm install URIjs
Browser
I guess you’ll manage to use the build tool or follow the instructions below to combine and minify the various files into URI.min.js - and I’m fairly certain you know how to <script src=".../URI.min.js"></script> that sucker, too.
Node.js and NPM
Install with npm install URIjs or add "URIjs" to the dependencies in your package.json.
// load URI.js
var URI = require('URIjs');
// load an optional module (e.g. URITemplate)
var URITemplate = require('URIjs/src/URITemplate');
URI("/foo/bar/baz.html")
.relativeTo("/foo/bar/sub/world.html")
// -> ../baz.html
RequireJS
Clone the URI.js repository or use a package manager to get URI.js into your project.
fixing URI.withinString() to not use backtracking prone regular expression URI.find_uri_expression anymore - (Issue #131)
fixing URI.withinString() to accept options ignore and ignoreHtml to allow better control over which detected URLs get handled - (Issue #117)
fixing URI.withinString() to accept option start to specify the RegExp used for finding the beginning of an URL (defaults to /\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi) - (Issue #115)
1.11.2 (August 14th 2013)
fixing regression for Node.js introduced by fixing unsafe eval by using UMD's root - (Issue #107)
Note: QUnit seems to be having some difficulties on IE8. While the jQuery-plugin tests fail, the plugin itself works. We’re still trying to figure out what’s making QUnit “lose its config state”.
URI.js
I always want to shoot myself in the head when looking at code like the following:
I still can’t believe javascript - the f**ing backbone-language of the web - doesn’t offer an API for mutating URLs. Browsers (Firefox) don’t expose the
Locationobject (the structure behind window.location). Yes, one could think of decomposed IDL attributes as a native URL management library. But it relies on the DOM element <a>, it’s slow and doesn’t offer any convenience at all.How about a nice, clean and simple API for mutating URIs:
URI.js is here to help with that.
API Example
See the About Page and API Docs for more stuff.
Using URI.js
URI.js (without plugins) has a gzipped weight of about 7KB - if you include all extensions you end up at about 13KB. So unless you need second level domain support and use URI templates, we suggest you don’t include them in your build. If you don’t need a full featured URI mangler, it may be worth looking into the much smaller parser-only alternatives listed below.
URI.js is available through npm, bower, Jam and manually from the build page:
Browser
I guess you’ll manage to use the build tool or follow the instructions below to combine and minify the various files into URI.min.js - and I’m fairly certain you know how to
<script src=".../URI.min.js"></script>that sucker, too.Node.js and NPM
Install with
npm install URIjsor add"URIjs"to the dependencies in yourpackage.json.RequireJS
Clone the URI.js repository or use a package manager to get URI.js into your project.
Minify
See the build tool or use Google Closure Compiler:
Resources
Documents specifying how URLs work:
Informal stuff
How other environments do things
Discussion on Hacker News
Alternatives
If you don’t like URI.js, you may like one of the following libraries. (If yours is not listed, drop me a line…)
URL Manipulation
URL Parsers
URI Template
Various
Authors
Contains Code From
License
URI.js is published under the MIT license and GPL v3.
Changelog
1.12.0 (January 23rd 2014)
.absoluteTo()to comply with RFC3986 Reference Resolution Examples - (Issue #113).normalizePath()to maintain leading parent references (../) for relative paths, while removing them for absolute paths - (Issue #133)URI.protocol_expressionto properly accept.in compliance with RFC 3986 - Scheme - (Issue #132)URI.withinString()to not use backtracking prone regular expressionURI.find_uri_expressionanymore - (Issue #131)URI.withinString()to accept optionsignoreandignoreHtmlto allow better control over which detected URLs get handled - (Issue #117)URI.withinString()to accept optionstartto specify the RegExp used for finding the beginning of an URL (defaults to/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi) - (Issue #115)1.11.2 (August 14th 2013)
fixing unsafe eval by using UMD's root- (Issue #107)1.11.1 (August 13th 2013)
.relativeTo()results caused by inconsistent URI component handling - (Issue #103).segment()to allow appending an empty element - (Issue #106).segment()to collapse empty elements in array notation1.11.0 (August 6th 2013)
.segmentCoded()to provide en/decoding interface to.segment()- (Issue #79).relativeTo()results - (Issue #78, Issue #95)URI.parse()andrelativeTo()- (Issue #100)URI.escapeQuerySpaceto control if query string should escape spaces using+or%20- (Issue #74)strictEncodeURIComponent()to work in Firefox 3.6 - (Issue #91).normalizePath()to properly resolve/.and/.//to/- (Issue #97).path()to return empty string if there is no path - (Issue #82)URI.decodeQuery()on malformed input - now returns original undecoded data - (Issue #87, Issue #92)URI.noConflict()- (Issue #84).readable()to decode the hash value as well - (Issue #90)jquery.URI.jsfrom temporarily usingwindow.locationas thehrefof an empty attribute of a DOM element - (Issue #94)getType()for IE8 with undefined value - (Issue #96)<a href="..."><blockquote cite="..."><link href="..."><base href="..."><script src="..."><form action="..."><input type="image" src="..."><img src="..."><area href="..."><iframe src="..."><embed src="..."><source src="..."><track src="...">jquery.URI.jsto use new DOM element infrastructure1.10.2 (April 15th 2013)
relativeTo()- (Issue #75)normalizePath()to not prepend./to relative paths - (Issue #76)1.10.1 (April 2nd 2013)
absoluteTo()to properly resolve relative scheme - (Issue #71)1.10.0 (March 16th 2013)
hasQuery()- (Issue #71)jquery.URI.js) - (Issue #69)1.9.1 (February 12th 2013)
URI(location)1.9.0 (February 11th 2013)
.setQuery()- (Issue #64).query()1.8.3 (January 9th 2013)
1.8.2 (December 27th 2012)
.fragmentPrefix()to configure prefix of fragmentURI and fragmentQuery extensions - (Issue #55).toString(),.valueOf()and.href()- (Issue #56).relativeTo()for descendants - (Issue #57)1.8.1 (November 15th 2012)
1.8.0 (November 13th 2012)
.resource()as compound of [path, query, fragment].duplicateQueryParameters()to control ifkey=valueduplicates have to be preserved or reduced (Issue #51).addQuery("empty")to properly add?empty- (Issue #46)http://username:pass:word@hostnamefile://C:/WINDOWS/foo.txtURI(location)to properly parse the URL - (Issue #52)Note: QUnit seems to be having some difficulties on IE8. While the jQuery-plugin tests fail, the plugin itself works. We’re still trying to figure out what’s making QUnit “lose its config state”.
1.7.4 (October 21st 2012)
/wiki/Help:IPA- (Issue #49)1.7.3 (October 11th 2012)
strictEncodeURIComponent()to properly encode*to%2Aimg.hrefbeing available - (Issue #48)1.7.2 (August 28th 2012)
.tld()-foot.sewould detectt.se- (Issue #42).absoluteTo()to comply with RFC 3986 Section 5.2.2 - (Issue #41)locationnot being available in non-browser environments like node.js (Issue #45 grimen)1.7.1 (August 14th 2012)
.segment()‘s append operation - (Issue #39)1.7.0 (August 11th 2012)
base- (Issue #33 LarryBattle).segment()accessor - (Issue #34)URI.encode()to strict URI encoding according to RFC3986URI.encodeReserved()to exclude reserved characters (according to RFC3986) from being encodedURITemplate()1.6.3 (June 24th 2012)
.absoluteTo()to join two relative paths properly - (Issue #29).clone()to copy an URI instance1.6.2 (June 23rd 2012)
.directory()now returns empty string if there is no directory.absoluteTo()to join two relative paths properly - (Issue #29)1.6.1 (May 19th 2012)
.domain()with dot-less hostnames - (Issue #27)1.6.0 (March 19th 2012)
javascript:,mailto:, …) support.scheme()as alias of.protocol().userinfo()to comply with terminology of RFC 3986src/jquery.URI.js1.5.0 (February 19th 2012)
1.4.3 (January 28th 2012)
1.4.2 (January 25th 2012)
1.4.1 (January 21st 2012)
1.4.0 (January 12th 2012)
URI.iso8859()andURI.unicode()to switch base charsets - (Issue #10, mortenn).iso8859()and.unicode()to convert an URI’s escape encoding1.3.1 (January 3rd 2011)
.hostname()1.3.0 (December 30th 2011)
.subdomain()convenience accessorURI("http://example.org").query(true)- (Issue #6)1.2.0 (December 29th 2011)
.equals()for URL comparison.pathname(),.directory(),.filename()and.suffix()according to RFC 3986 3.3+according to application/x-www-form-urlencodedURI.buildQuery()to build duplicate key=value combinationsURI(string, string)constructor to conform with the specification.readable()for humanly readable representation of encoded URIs1.1.0 (December 28th 2011)
URI.withinString().normalizeProtocol()to lowercase protocols.normalizeHostname()to lowercase hostnames{foo: null}Algorithm for collecting URL parameters{foo: null, bar: ""}to “?foo&bar=” Algorithm for serializing URL parameters1.0.0 (December 27th 2011)