Clean Urls

Hiding the Breadcrumb Trail

When the user opens and email in our example app, we drop a breadcrumb at the 'inbox' scene so that the user can revisit it. By default, the Navigation router stores the breadcrumb trail in the Url. For example, the Url for opening an email with an id of 12 is '/mail?id=12&crumb=%2F'. The crumb parameter in the query string holds the Url that returns the user to their inbox.

Storing the crumbs in the Url has the advantage that when a user bookmarks a scene they also bookmark the breadcrumb trail. But one of the disadvantages is that it makes the Url scruffy. We hide the breadcrumb trail from the Url by passing a MobileHistoryManager into the StateNavigator constructor. The MobileHistoryManager turns the Url that opens the email with an id of 12 into '/mail?id=12'.

var stateNavigator = new Navigation.StateNavigator([
  {key: 'inbox', route: ''},
  {key: 'mail', trackCrumbTrail: true, defaultTypes: {id: 'number'}}
], new NavigationReactMobile.MobileHistoryManager());

Patching Bookmarks

Removing the breadcrumb trail from the Url breaks bookmarking. A user visiting a bookmarked email will find that the Hyperlink taking them back to their inbox is disabled. The bookmark takes the user straight to their open email, bypassing the inbox, so the breadcrumb trail is empty and they can't navigate back.

We can re-enable the Hyperlink by prepopulating the breadcrumb trail so it looks like the user came from the 'inbox' scene. For example, when a user clicks on a bookmarked Url of '/mail?id=12' we start the application with the Url of '/mail?id=12&crumb=%2F' instead. We can build this Url by using the Navigation router's fluent navigation to simulate the user opening the email from their inbox.

var url = stateNavigator.fluent()
  .navigate('inbox')
  .navigate('mail', {id: 12}).url;

We change the startup Url by passing a function into the MobileHistoryManager constructor. The function receives the browser Url and we use fluent navigation to return the new Url with the 'inbox' breadcrumb included. We extract the bookmarked email Id from the incoming Url using the parseLink function on the stateNavigator.

new NavigationReactMobile.MobileHistoryManager(function(url) {
  var {state, data} = stateNavigator.parseLink(url);
  return stateNavigator.fluent()
    .navigate('inbox')
    .navigate(state.key, data).url;
})

Removing Hashes

By default, the MobileHistoryManager operates in hash history mode. For example, the full Url that opens an email of id 12 is 'https://domain/#/mail?id=12'. To remove the hash and clean up the Url so it reads 'https://domain/mail?id=12', we pass an empty string as the second parameter to the MobileHistoryManager constructor. If we wanted our Url to look like 'https://domain/app/mail?id=12', we’d pass the 'app' base path as the second parameter instead.

new NavigationReactMobile.MobileHistoryManager(function(url) {
  var {state, data} = stateNavigator.parseLink(url);
  return stateNavigator.fluent()
    .navigate('inbox')
    .navigate(state.key, data).url;
}, '')

Note

You should beware of using the MobileHistoryManager in hash history mode in production because not all browsers fire the popstate event when the hash changes