# URI.js # * [About](http://medialize.github.io/URI.js/) * [Understanding URIs](http://medialize.github.io/URI.js/about-uris.html) * [Documentation](http://medialize.github.io/URI.js/docs.html) * [jQuery URI Plugin](http://medialize.github.io/URI.js/jquery-uri-plugin.html) * [Author](http://rodneyrehm.de/en/) --- I always want to shoot myself in the head when looking at code like the following: ```javascript var url = "http://example.org/foo?bar=baz"; var separator = url.indexOf('?') > -1 ? '&' : '?'; url += separator + encodeURIComponent("foo") + "=" + encodeURIComponent("bar"); ``` 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](http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#url-decomposition-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: ```javascript var url = new URI("http://example.org/foo?bar=baz"); url.addQuery("foo", "bar"); ``` URI.js is here to help with that. ## API Example ## ```javascript // mutating URLs URI("http://example.org/foo.html?hello=world") .username("rodneyrehm") // -> http://rodneyrehm@example.org/foo.html?hello=world .username("") // -> http://example.org/foo.html?hello=world .directory("bar") // -> http://example.org/bar/foo.html?hello=world .suffix("xml") // -> http://example.org/bar/foo.xml?hello=world .query("") // -> http://example.org/bar/foo.xml .tld("com") // -> http://example.com/bar/foo.xml .query({ foo: "bar", hello: ["world", "mars"] }); // -> http://example.com/bar/foo.xml?foo=bar&hello=world&hello=mars // cleaning things up URI("?&foo=bar&&foo=bar&foo=baz&") .normalizeQuery(); // -> ?foo=bar&foo=baz // working with relative paths URI("/foo/bar/baz.html") .relativeTo("/foo/bar/world.html"); // -> ./baz.html URI("/foo/bar/baz.html") .relativeTo("/foo/bar/sub/world.html") // -> ../baz.html .absoluteTo("/foo/bar/sub/world.html"); // -> /foo/bar/baz.html // URI Templates URI.expand("/foo/{dir}/{file}", { dir: "bar", file: "world.html" }); // -> /foo/bar/world.html ``` See the [About Page](http://medialize.github.io/URI.js/) and [API Docs](http://medialize.github.io/URI.js/docs.html) 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](#alternatives). URI.js is available through [npm](http://npmjs.org/), [bower](http://bower.io/), [Jam](http://jamjs.org/) and manually from the [build page](http://medialize.github.io/URI.js/build.html): ```bash # 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](http://medialize.github.io/URI.js/build.html) or follow the [instructions below](#minify) to combine and minify the various files into URI.min.js - and I'm fairly certain you know how to `` that sucker, too. ### Node.js and NPM ### Install with `npm install URIjs` or add `"URIjs"` to the dependencies in your `package.json`. ```javascript // 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. ```javascript require.config({ paths: { URIjs: 'where-you-put-uri.js/src' } }); require(['URIjs/URI'], function(URI) { console.log("URI.js and dependencies: ", URI("//amazon.co.uk").is('sld') ? 'loaded' : 'failed'); }); require(['URIjs/URITemplate'], function(URITemplate) { console.log("URITemplate.js and dependencies: ", URITemplate._cache ? 'loaded' : 'failed'); }); ``` ## Minify ## See the [build tool](http://medialize.github.io/URI.js/build.html) or use [Google Closure Compiler](http://closure-compiler.appspot.com/home): ``` // ==ClosureCompiler== // @compilation_level SIMPLE_OPTIMIZATIONS // @output_file_name URI.min.js // @code_url http://medialize.github.io/URI.js/src/IPv6.js // @code_url http://medialize.github.io/URI.js/src/punycode.js // @code_url http://medialize.github.io/URI.js/src/SecondLevelDomains.js // @code_url http://medialize.github.io/URI.js/src/URI.js // @code_url http://medialize.github.io/URI.js/src/URITemplate.js // ==/ClosureCompiler== ``` ## Resources ## Documents specifying how URLs work: * [URL - Living Standard](http://url.spec.whatwg.org/) * [RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax](http://tools.ietf.org/html/rfc3986) * [RFC 3987 - Internationalized Resource Identifiers (IRI)](http://tools.ietf.org/html/rfc3987) * [RFC 2732 - Format for Literal IPv6 Addresses in URL's](http://tools.ietf.org/html/rfc2732) * [Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)](http://tools.ietf.org/html/rfc3492) * [application/x-www-form-urlencoded](http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type) (Query String Parameters) and [application/x-www-form-urlencoded encoding algorithm](http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#application/x-www-form-urlencoded-encoding-algorithm) * [What every web developer must know about URL encoding](http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding) Informal stuff * [Parsing URLs for Fun and Profit](http://tools.ietf.org/html/draft-abarth-url-01) * [Naming URL components](http://tantek.com/2011/238/b1/many-ways-slice-url-name-pieces) How other environments do things * [Java URI Class](http://docs.oracle.com/javase/7/docs/api/java/net/URI.html) * [Java Inet6Address Class](http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Inet6Address.html) * [Node.js URL API](http://nodejs.org/docs/latest/api/url.html) [Discussion on Hacker News](https://news.ycombinator.com/item?id=3398837) ### Forks / Code-borrow ### * [node-dom-urls](https://github.com/passy/node-dom-urls) passy's partial implementation of the W3C URL Spec Draft for Node * [urlutils](https://github.com/cofounders/urlutils) cofounders' `window.URL` constructor for Node ### 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…) #### Polyfill #### * [DOM-URL-Polyfill](https://github.com/arv/DOM-URL-Polyfill/) arv's polyfill of the [DOM URL spec](https://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#interface-urlutils) for browsers * [inexorabletash](https://github.com/inexorabletash/polyfill/#whatwg-url-api) inexorabletash's [WHATWG URL API](http://url.spec.whatwg.org/) #### URL Manipulation #### * [The simple URL Mutation "Hack"](http://jsfiddle.net/rodneyrehm/KkGUJ/) ([jsPerf comparison](http://jsperf.com/idl-attributes-vs-uri-js)) * [URL.js](https://github.com/ericf/urljs) * [furl (Python)](https://github.com/gruns/furl) * [mediawiki Uri](https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/resources/mediawiki/mediawiki.Uri.js?view=markup) (needs mw and jQuery) * [jurlp](https://github.com/tombonner/jurlp) * [jsUri](http://code.google.com/p/jsuri/) #### URL Parsers #### * [The simple URL Mutation "Hack"](http://jsfiddle.net/rodneyrehm/KkGUJ/) ([jsPerf comparison](http://jsperf.com/idl-attributes-vs-uri-js)) * [URI Parser](http://blog.stevenlevithan.com/archives/parseuri) * [jQuery-URL-Parser](https://github.com/allmarkedup/jQuery-URL-Parser) * [Google Closure Uri](http://closure-library.googlecode.com/svn/docs/closure_goog_uri_uri.js.html) * [URI.js by Gary Court](https://github.com/garycourt/uri-js) #### URI Template #### * [uri-template](https://github.com/rezigned/uri-template.js) (supporting extraction as well) by Rezigne * [uri-templates](https://github.com/geraintluff/uri-templates) (supporting extraction as well) by Geraint Luff * [uri-templates](https://github.com/marc-portier/uri-templates) by Marc Portier * [uri-templates](https://github.com/geraintluff/uri-templates) by Geraint Luff (including reverse operation) * [URI Template JS](https://github.com/fxa/uritemplate-js) by Franz Antesberger * [Temple](https://github.com/brettstimmerman/temple) by Brett Stimmerman * ([jsperf comparison](http://jsperf.com/uri-templates/2)) #### Various #### * [TLD.js](https://github.com/oncletom/tld.js) - second level domain names * [Public Suffix](http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1) - second level domain names * [uri-collection](https://github.com/scivey/uri-collection) - underscore based utility for working with many URIs ## Authors ## * [Rodney Rehm](https://github.com/rodneyrehm) * [Various Contributors](https://github.com/medialize/URI.js/graphs/contributors) ## Contains Code From ## * [punycode.js](http://mths.be/punycode) - Mathias Bynens * [IPv6.js](http://intermapper.com/support/tools/IPV6-Validator.aspx) - Rich Brown - (rewrite of the original) ## License ## URI.js is published under the [MIT license](http://www.opensource.org/licenses/mit-license). Until version 1.13.2 URI.js was also published under the [GPL v3](http://opensource.org/licenses/GPL-3.0) license - but as this dual-licensing causes more questions than helps anyone, it was dropped with version 1.14.0. ## Changelog ## ### 1.14.1 (October 1st 2014) ### * fixing handling of String instances (not string primitives) - ([Issue #146](https://github.com/medialize/URI.js/issues/146)) * fixing Firefox [`.watch()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch) interfering with `.parseQuery()` - ([Issue #169](https://github.com/medialize/URI.js/issues/169)) * fixing [`addQuery()`](http://medialize.github.io/URI.js/docs.html#search-add) to not throw error on null value - ([Issue #171](https://github.com/medialize/URI.js/issues/171)) ### 1.14.0 (September 8th 2014) ### * adding Hungarian second level domains - ([Issue #159](https://github.com/medialize/URI.js/issues/159)) * adding ``](http://www.w3.org/html/wg/drafts/html/master/text-level-semantics.html#the-a-element) * [`
`](http://www.w3.org/html/wg/drafts/html/master/grouping-content.html#the-blockquote-element) * [``](http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-link-element) * [``](http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-base-element) * [`