@ngdoc overview @name Developer Guide: Angular Services: Using $location @description # What does it do? The `$location` service parses the URL in the browser address bar (based on the {@link https://developer.mozilla.org/en/window.location window.location}) and makes the URL available to your application. Changes to the URL in the address bar are reflected into $location service and changes to $location are reflected into the browser address bar. **The $location service:** - Exposes the current URL in the browser address bar, so you can - Watch and observe the URL. - Change the URL. - Maintains synchronization between itself and the browser's URL when the user - Changes the address in the browser's address bar. - Clicks the back or forward button in the browser (or clicks a History link). - Clicks on a link in the page. - Represents the URL object as a set of methods (protocol, host, port, path, search, hash). ## Comparing $location to window.location
| window.location | $location service | |
|---|---|---|
| purpose | allow read/write access to the current browser location | same | 
| API | exposes "raw" object with properties that can be directly modified | exposes jQuery-style getters and setters | 
| integration with angular application life-cycle | none | knows about all internal life-cycle phases, integrates with $watch, ... | 
| seamless integration with HTML5 API | no | yes (with a fallback for legacy browsers) | 
| aware of docroot/context from which the application is loaded | no - window.location.path returns "/docroot/actual/path" | yes - $location.path() returns "/actual/path" | 
$locationProvider.html5Mode(true).hashPrefix('!');
## Getter and setter methods
`$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host,
port) and getter / setter methods for url, path, search, hash:
// get the current path
$location.path();
// change the path
$location.path('/newValue')
All of the setter methods return the same `$location` object to allow chaining. For example, to
change multiple segments in one go, chain setters like this:
$location.path('/newValue').search({key: value});
## Replace method
There is a special `replace` method which can be used to tell the $location service that the next
time the $location service is synced with the browser, the last history record should be replaced
instead of creating a new one. This is useful when you want to implement redirection, which would
otherwise break the back button (navigating back would retrigger the redirection). To change the
current URL without creating a new browser history record you can call:
  $location.path('/someNewPath');
  $location.replace();
  // or you can chain these as: $location.path('/someNewPath').replace();
Note that the setters don't update `window.location` immediately. Instead, the `$location` service is
aware of the {@link api/ng.$rootScope.Scope scope} life-cycle and coalesces multiple `$location`
mutations into one "commit" to the `window.location` object during the scope `$digest` phase. Since
multiple changes to the $location's state will be pushed to the browser as a single change, it's
enough to call the `replace()` method just once to make the entire "commit" a replace operation
rather than an addition to the browser history. Once the browser is updated, the $location service
resets the flag set by `replace()` method and future mutations will create new history records,
unless `replace()` is called again.
### Setters and character encoding
You can pass special characters to `$location` service and it will encode them according to rules
specified in {@link http://www.ietf.org/rfc/rfc3986.txt RFC 3986}. When you access the methods:
- All values that are passed to `$location` setter methods, `path()`, `search()`, `hash()`, are
encoded.
- Getters (calls to methods without parameters) return decoded values for the following methods
`path()`, `search()`, `hash()`.
- When you call the `absUrl()` method, the returned value is a full url with its segments encoded.
- When you call the `url()` method, the returned value is path, search and hash, in the form
`/path?search=a&b=c#hash`. The segments are encoded as well.
# Hashbang and HTML5 Modes
`$location` service has two configuration modes which control the format of the URL in the browser
address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
HTML5 {@link http://www.w3.org/TR/html5/history.html History API}. Applications use the same API in
both modes and the `$location` service will work with appropriate URL segments and browser APIs to
facilitate the browser URL change and history management.
 
| Hashbang mode | HTML5 mode | |
|---|---|---|
| configuration | the default | { html5Mode: true } | 
| URL format | hashbang URLs in all browsers | regular URLs in modern browser, hashbang URLs in old browser | 
| <a href=""> link rewriting | no | yes | 
| requires server-side configuration | no | yes | 
it('should show example', inject(
  function($locationProvider) {
    $locationProvider.html5Mode(false);
    $locationProvider.hashPrefix('!');
  },
  function($location) {
    // open http://example.com/base/index.html#!/a
    $location.absUrl() == 'http://example.com/base/index.html#!/a'
    $location.path() == '/a'
    $location.path('/foo')
    $location.absUrl() == 'http://example.com/base/index.html#!/foo'
    $location.search() == {}
    $location.search({a: 'b', c: true});
    $location.absUrl() == 'http://example.com/base/index.html#!/foo?a=b&c'
    $location.path('/new').search('x=y');
    $location.absUrl() == 'http://example.com/base/index.html#!/new?x=y'
  }
));
### Crawling your app
To allow indexing of your AJAX application, you have to add special meta tag in the head section of
your document:
This will cause crawler bot to request links with `_escaped_fragment_` param so that your server
can recognize the crawler and serve a HTML snapshots. For more information about this technique,
see {@link http://code.google.com/web/ajaxcrawling/docs/specification.html Making AJAX Applications
Crawlable}.
## HTML5 mode
In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
through the HTML5 history API, which allows for use of regular URL path and search segments,
instead of their hashbang equivalents. If the HTML5 History API is not supported by a browser, the
`$location` service will fall back to using the hashbang URLs automatically. This frees you from
having to worry about whether the browser displaying your app supports the history API  or not; the
`$location` service transparently uses the best available option.
- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
- Opening hashbang URL in a modern browser -> rewrites to a regular URL
### Example
it('should show example', inject(
  function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('!');
  },
  function($location) {
    // in browser with HTML5 history support:
    // open http://example.com/#!/a -> rewrite to http://example.com/a
    // (replacing the http://example.com/#!/a history record)
    $location.path() == '/a'
    $location.path('/foo');
    $location.absUrl() == 'http://example.com/foo'
    $location.search() == {}
    $location.search({a: 'b', c: true});
    $location.absUrl() == 'http://example.com/foo?a=b&c'
    $location.path('/new').search('x=y');
    $location.url() == 'new?x=y'
    $location.absUrl() == 'http://example.com/new?x=y'
    // in browser without html5 history support:
    // open http://example.com/new?x=y -> redirect to http://example.com/#!/new?x=y
    // (again replacing the http://example.com/new?x=y history item)
    $location.path() == '/new'
    $location.search() == {x: 'y'}
    $location.path('/foo/bar');
    $location.path() == '/foo/bar'
    $location.url() == '/foo/bar?x=y'
    $location.absUrl() == 'http://example.com/#!/foo/bar?x=y'
  }
));
### Fallback for legacy browsers
For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
path and search. If the history API is not supported by a browser, `$location` supplies a Hasbang
URL. This frees you from having to worry about whether the browser viewing your app supports the
history API  or not; the `$location` service makes this transparent to you.
### Html link rewriting
When you use HTML5 history API mode, you will need different links in different browsers, but all you
have to do is specify regular URL links, such as: `link`
When a user clicks on this link,
- In a legacy browser, the URL changes to `/index.html#!/some?foo=bar`
- In a modern browser, the URL changes to `/some?foo=bar`
In cases like the following, links are not rewritten; instead, the browser will perform a full page
reload to the original link.
- Links that contain `target` element
describe('serviceUnderTest', function() {
  beforeEach(module(function($provide) {
    $provide.factory('serviceUnderTest', function($location){
      // whatever it does...
    });
  });
  it('should...', inject(function($location, $rootScope, serviceUnderTest) {
    $location.path('/new/path');
    $rootScope.$apply();
    // test whatever the service should do...
  }));
});
# Migrating from earlier AngularJS releases
In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
search methods. With this release, the `$location` service processes path and search methods and
then uses the information it obtains to compose hashbang URLs (such as
`http://server.com/#!/path?search=a`), when necessary.
## Changes to your code
| Navigation inside the app | Change to | 
|---|---|
| $location.href = value $location.hash = value $location.update(value) $location.updateHash(value) | $location.path(path).search(search) | 
| $location.hashPath = path | $location.path(path) | 
| $location.hashSearch = search | $location.search(search) | 
| Navigation outside the app | Use lower level API | 
| $location.href = value $location.update(value) | $window.location.href = value | 
| $location[protocol | host | port | path | search] | $window.location[protocol | host | port | path | search] | 
| Read access | Change to | 
| $location.hashPath | $location.path() | 
| $location.hashSearch | $location.search() | 
| $location.href $location.protocol $location.host $location.port $location.hash | $location.absUrl() $location.protocol() $location.host() $location.port() $location.path() + $location.search() | 
| $location.path $location.search | $window.location.path $window.location.search |