YUI 3: History
Client-side changes to a web page's content and structure are not recorded by the browser's history engine. As a consequence, the navigation buttons (back/forward) we've learned to use as we traverse the World Wide Web of documents don't usually serve us well when we begin exploring the World Wide Web of applications. Bookmarking, too, is problematic in web applications, as the application can change state hundreds of times through the course of a session without any change to the original document's URL. These are significant problems in the current paradigm of web application development.
The History Utility is a utility designed to facilitate the creation of web applications in which the navigation buttons are fully functional and in which broad aspects of an application's state — what panels are open, what tabs are active, etc. — can be bookmarked.
More Information
- Examples: History Utility in action.
- API Documentation: View the full API documentation for the History Utility.
- Download: History Utility as part of the full YUI Library.
- Free Hosting on our fast edge servers with combo-loading.
- License: BSD.
Getting Started
Include Dependencies
The easiest way to include the source files for the History Utility and its dependencies is to add the YUI seed file to your page, using the following script tag, and allow the YUI instance to download any additional files which maybe required:
The YUI instance will automatically pull down the History Utility's source files, along
with any dependent files missing from the page, when the history
module is used in your code. This helps you avoid having to manually manage the
list of files which need to be included on your page to support multiple components,
while also optimizing your initial page weight by loading files only when they are
required.
If you do want to include file dependencies manually on your page, the YUI Configurator can be used to determine the list of files you need to include in order to use the History Utility.
The YUI Instance
Once you have the YUI seed file on your page (yui-min.js), you can
create a new YUI instance for your application to use, and populate it
with the modules you need, specified as the first set of arguments to the
use method:
The last argument passed to use is a callback function. The callback function will be
invoked as soon as the YUI instance is done downloading any required files missing from
your page, and populated the local YUI instance with the classes which make up
the history module and any modules it depends on.
A reference to the populated YUI instance (Y) is passed back to the
callback function inside which you can start writing your application code based on your own, custom
instance of YUI.
For more information on creating instances of YUI and the
use method, see the
YUI Global object documentation.
Using the History Utility
This section describes how to use the History Utility in further detail. It contains these subsections:
Required markup
The History Utility requires the following in-page markup:
Notes:
- The IFrame is only used to support Internet Explorer prior to version 8, and IE8 in compatibility mode. If the markup is dynamically generated on the server (as a result of running a PHP script for example), you may want to create the IFrame only for the browsers that need it (use server side user agent sniffing)
- The asset loaded in the IFrame must be retrieved from the same domain as your page
(use a relative path for the
srcattribute to make sure of that) - This markup should appear right after the opening
<bodytag.
The asset loaded in the IFrame must be an HTML document. A blank html document will do just fine:
Don't forget to hide the IFrame using the following CSS code:
Module registration
A user interface module is simply a visible item on your page with which the user can interact. As such, modules are not immutable and their state is subject to change over time. If you wish to record the history of states visited by a specific module during a single browser session, to allow the user to navigate through that history using the browser's back/forward button, and to bookmark the page with your module in a specific state, you must first register it with the History Utility.
In order to register a module, use the register method of the History Utility, passing in
the module identifier (a non-empty string that uniquely identifies your module) and the initial state of your module
(i.e. the state of your module corresponding to the earliest history entry within the current browser session)
as a string.
Getting the initial state of the module is the trickiest part of this process. Indeed, the user might have previously
visited your page and bookmarked it with your module in a specific state. If the user later on comes back to your page
using the same bookmark, you will likely wish to restore your module in the same state it was in when the page was
bookmarked. To retrieve this "bookmarked state", simply call the getBookmarkedState method of the
History Utility, passing in your module identifier:
Of course, you also need a "default state" for your module in case the user accessed the page without using a bookmark.
Having determined whether there is a bookmarked state in the code example above (getBookmarkedState will
have returned null if there was no bookmarked state), the initial state of your module can be assigned as follows:
The next step in configuring your module to use with the History Utility is to define what action should be taken when the state of your module changes:
Finally, complete your module registration by calling the register method of the History Utility.
This method returns a history module object, which will fire the history:moduleStateChange event whenever
its state changes. You should subscribe to this event using the previously defined handler.
Note: You may register as many modules as you want, but you must register at least one module before initializing the History Utility. Modules cannot be registered once the History Utility has been initialized.
Initializing the History Utility
The History Utility initializes itself asynchronously and some of its methods cannot be called until it is
fully initialized. You may want to know when this event occurs. In order to do that, subscribe to History Utility history:ready event.
One common task you'll find yourself executing in your History Utility history:ready event handler
is retrieving the current state of your module and updating its UI accordingly. Why would the current state of your module
be different from its initial state? Remember that the "initial" state of your module corresponds to the earliest
history entry. The History Utility history:ready event will be fired every time the user visits the
page. If the user comes back to the page using the browser's back button, the state of your module will correspond to the
latest history entry — that is the last state of your module before the user left the page. You can retrieve
the current state of your module using the getCurrentState method of the History Utility,
passing in your module identifier.
The initialization of the History Utility will therefore look like so:
Storing New History Entries
Use the navigate method of the History Utility to store a new state in the browser history,
passing in the identifier of the module which state has changed, and a string representing the new state of the
specified module (if you wish to modify the state of several modules in one single history entry, use the
multiNavigate method instead)
Known Limitations
- The History Utility uses the URL fragment identifier to store state information. This means that there is a limit to how much information can be stored. Indeed, each browser has a built-in limit to how long a URL can be, and this limit is browser dependent. For example, on Internet Explorer, this limit is 2083 characters. Also, keep in mind that this limit applies to the entire URL, not just the fragment identifier.
- A string is a one-dimensional way of saving state information. It is possible to save multi-dimension state information (such as the collapsed/expanded state of each node of a treeview) into a one-dimensional string. However, the maximum length of a state identifier limits this to comparatively simple cases.
- Web browsers never send the URL fragment identifier to the server. This means that some client-side processing is required in order to handle bookmarks. It is important to keep this amount of processing to a minimum in order not to degrade user experience. However, if an additional HTTP request at startup is not an issue, it is possible to send the URL fragment identifier back to the server and have the server do some processing instead (such as generating the appropriate markup)
- All browsers will forget part or all of the history if the page gets forcibly refreshed. This will happen on Internet Explorer by pressing Ctrl+F5, and on Firefox by pressing Ctrl+F5 or Shift-Ctrl-R.
- On Internet Explorer, the title of the documents added to the history, listed in the browser's history drop down menu, is not correct. Instead of showing the title of each document, it shows part of the URL of each page.
Support & Community
Forums & Blog
YUI 3 discussion forums are hosted on YUILibrary.com.
In addition, please visit the YUIBlog for updates and articles about the YUI Library written by the library's developers.
Filing Bugs & Feature Requests
The YUI Library's public bug tracking and feature request repositories are located on the YUILibrary.com site. Before filing new feature requests or bug reports, please review our reporting guidelines.

