diff --git a/app/assets/javascripts/discourse/components/url.js b/app/assets/javascripts/discourse/components/url.js
index b4062a376..6589e1a83 100644
--- a/app/assets/javascripts/discourse/components/url.js
+++ b/app/assets/javascripts/discourse/components/url.js
@@ -48,6 +48,7 @@ Discourse.URL = Em.Object.createWithMixins({
     @param {String} path The path we are routing to.
   **/
   routeTo: function(path) {
+
     var oldPath = window.location.pathname;
     path = path.replace(/https?\:\/\/[^\/]+/, '');
 
diff --git a/app/assets/javascripts/discourse/routes/discourse_location.js b/app/assets/javascripts/discourse/routes/discourse_location.js
index 8b92cb4a9..c23d19130 100644
--- a/app/assets/javascripts/discourse/routes/discourse_location.js
+++ b/app/assets/javascripts/discourse/routes/discourse_location.js
@@ -3,7 +3,8 @@
 */
 
 var get = Ember.get, set = Ember.set;
-var popstateReady = false;
+var popstateFired = false;
+var supportsHistoryState = window.history && 'state' in window.history;
 
 // Thanks: https://gist.github.com/kares/956897
 var re = /([^&=]+)=?([^&]*)/g;
@@ -46,9 +47,6 @@ Ember.DiscourseLocation = Ember.Object.extend({
 
   init: function() {
     set(this, 'location', get(this, 'location') || window.location);
-    if ( $.inArray('state', $.event.props) < 0 ) {
-      jQuery.event.props.push('state');
-    }
     this.initState();
   },
 
@@ -66,10 +64,18 @@ Ember.DiscourseLocation = Ember.Object.extend({
       this.set('queryParams', $.parseParams(location.search));
     }
 
+    set(this, 'history', get(this, 'history') || window.history);
     this.replaceState(this.formatURL(this.getURL()));
-    set(this, 'history', window.history);
   },
 
+  /**
+    Will be pre-pended to path upon state change
+
+    @property rootURL
+    @default '/'
+  */
+  rootURL: '/',
+
   /**
     @private
 
@@ -96,9 +102,10 @@ Ember.DiscourseLocation = Ember.Object.extend({
     @param path {String}
   */
   setURL: function(path) {
+    var state = this.getState();
     path = this.formatURL(path);
-    if (this.getState() && this.getState().path !== path) {
-      popstateReady = true;
+
+    if (state && state.path !== path) {
       this.pushState(path);
     }
   },
@@ -113,10 +120,10 @@ Ember.DiscourseLocation = Ember.Object.extend({
     @param path {String}
   */
   replaceURL: function(path) {
+    var state = this.getState();
     path = this.formatURL(path);
 
-    if (this.getState() && this.getState().path !== path) {
-      popstateReady = true;
+    if (state && state.path !== path) {
       this.replaceState(path);
     }
   },
@@ -125,14 +132,13 @@ Ember.DiscourseLocation = Ember.Object.extend({
    @private
 
    Get the current `history.state`
+   Polyfill checks for native browser support and falls back to retrieving
+   from a private _historyState variable
 
    @method getState
   */
   getState: function() {
-    var historyState = get(this, 'history').state;
-    if (historyState) return historyState;
-
-    return {path: window.location.pathname};
+    return supportsHistoryState ? get(this, 'history').state : this._historyState;
   },
 
   /**
@@ -144,9 +150,17 @@ Ember.DiscourseLocation = Ember.Object.extend({
    @param path {String}
   */
   pushState: function(path) {
-    if (!window.history.pushState) return;
-    this.set('currentState', { path: path } );
-    window.history.pushState({ path: path }, null, path);
+    var state = { path: path };
+
+    get(this, 'history').pushState(state, null, path);
+
+    // store state if browser doesn't support `history.state`
+    if (!supportsHistoryState) {
+      this._historyState = state;
+    }
+
+    // used for webkit workaround
+    this._previousURL = this.getURL();
   },
 
   /**
@@ -158,9 +172,17 @@ Ember.DiscourseLocation = Ember.Object.extend({
    @param path {String}
   */
   replaceState: function(path) {
-    if (!window.history.replaceState) return;
-    this.set('currentState', { path: path } );
-    window.history.replaceState({ path: path }, null, path);
+    var state = { path: path };
+
+    get(this, 'history').replaceState(state, null, path);
+
+    // store state if browser doesn't support `history.state`
+    if (!supportsHistoryState) {
+      this._historyState = state;
+    }
+
+    // used for webkit workaround
+    this._previousURL = this.getURL();
   },
 
 
@@ -175,7 +197,10 @@ Ember.DiscourseLocation = Ember.Object.extend({
 
   // When our query params change, update the URL
   queryParamsStringChanged: function() {
-    this.replaceState(this.formatURL(this.getURL()));
+    var loc = this;
+    Em.run.next(function () {
+      loc.replaceState(loc.formatURL(loc.getURL()));
+    });
   }.observes('queryParamsString'),
 
   /**
@@ -191,21 +216,13 @@ Ember.DiscourseLocation = Ember.Object.extend({
     var guid = Ember.guidFor(this),
         self = this;
 
-    $(window).bind('popstate.ember-location-'+guid, function(e) {
-      if (e.state) {
-        var currentState = self.get('currentState');
-        if (currentState) {
-          var url = e.state.path,
-              rootURL = (Discourse.BaseUri === undefined ? "/" : Discourse.BaseUri);
-
-          rootURL = rootURL.replace(/\/$/, '');
-          url = url.replace(rootURL, '');
-          callback(url);
-        } else {
-          this.set('currentState', e.state);
-        }
+    Ember.$(window).on('popstate.ember-location-'+guid, function(e) {
+      // Ignore initial page load popstate event in Chrome
+      if (!popstateFired) {
+        popstateFired = true;
+        if (self.getURL() === self._previousURL) { return; }
       }
-
+      callback(self.getURL());
     });
   },
 
@@ -218,27 +235,21 @@ Ember.DiscourseLocation = Ember.Object.extend({
     @param url {String}
   */
   formatURL: function(url) {
-    var rootURL = (Discourse.BaseUri === undefined ? "/" : Discourse.BaseUri);
+    var rootURL = get(this, 'rootURL');
 
     if (url !== '') {
       rootURL = rootURL.replace(/\/$/, '');
     }
 
-    // remove prefix from URL if it is already in url - i.e. /discourse/t/... -> /t/if rootURL is /discourse
-    // this sometimes happens when navigating to already visited location
-    if ((rootURL.length > 1) && (url.substring(0, rootURL.length + 1) === (rootURL + "/")))
-    {
-      url = url.substring(rootURL.length);
-    }
-
     return rootURL + url + this.get('queryParamsString');
   },
 
   willDestroy: function() {
     var guid = Ember.guidFor(this);
 
-    Ember.$(window).unbind('popstate.ember-location-'+guid);
+    Ember.$(window).off('popstate.ember-location-'+guid);
   }
+
 });
 
 Ember.Location.registerImplementation('discourse_location', Ember.DiscourseLocation);
diff --git a/app/assets/javascripts/discourse/routes/topic_from_params_route.js b/app/assets/javascripts/discourse/routes/topic_from_params_route.js
index 097b681a8..368e5444f 100644
--- a/app/assets/javascripts/discourse/routes/topic_from_params_route.js
+++ b/app/assets/javascripts/discourse/routes/topic_from_params_route.js
@@ -9,6 +9,7 @@
 Discourse.TopicFromParamsRoute = Discourse.Route.extend({
 
   setupController: function(controller, params) {
+
     params = params || {};
     params.track_visit = true;
 
@@ -34,7 +35,6 @@ Discourse.TopicFromParamsRoute = Discourse.Route.extend({
         composerController = this.controllerFor('composer');
 
     postStream.refresh(params).then(function () {
-
       // The post we requested might not exist. Let's find the closest post
       var closest = postStream.closestPostNumberFor(params.nearPost) || 1;
 
@@ -53,11 +53,7 @@ Discourse.TopicFromParamsRoute = Discourse.Route.extend({
           ignoreIfChanged: true
         });
       }
-
-
     });
-
-
   }
 
 });