Home Overview Demos/Webs News Download/Install Docs/Support Investors/Partners Commercial Tutorial: Simple ItsNat (Core) Application Tutorial: Simple ItsNat (Core) STATELESS Application Tutorial: Single Page Interface SEO Compatible Web Site With ItsNat STATEFUL Using HASHBANGS Tutorial: Single Page Interface SEO Compatible Web Site With ItsNat STATELESS Using HASHBANGS Tutorial: Single Page Interface SEO Compatible Web Site With ItsNat STATEFUL Using HISTORY API Tutorial: Single Page Interface SEO Compatible Web Site With ItsNat STATELESS Using HISTORY API Tutorial: Hybrid Client-Server Centric Programming
Tutorial: Single Page Interface SEO Compatible Web Site With ItsNat STATEFUL Using History API

Last update: 2015, Sept. 27  

Introduction

Introduction/Setup
SPI, SEO compatiblity and History API
Web application set-up
Creating the ItsNat servlet
Main page processing
Main page processing and history api
Infrastructure of fundamental states
Conclusion
Download and Online Demo

This tutorial shows the History API SPI web site version of the stateful using hashbangs tutorial, reading the hashbang version first is highly recommended, main ItsNat concepts are not going to be repeated in this tutorial and some parts of this version are identical to the hashbang based.

The objective of this tutorial is to make a Single Page Interface Stateful SEO Compatible using History API.

To understand this tutorial some basic knowledge of ItsNat is required.

The History API is a modern JavaScript specification that allows programmatic manipulation of the page/URL history of your browser. The History API is extremely useful in a Single Page Interface SEO compatible context because it provides the finest, elegant, user transparent and near perfect way of simulating page based web sites and in the same time avoiding page reload, that's it, SPI SEO compatible. End users are not going to see a big difference between the real page based and the History API version, or yes, they are going to appreciate some big visual differences like a better performance when changing states (pages) because only the changed part is loaded, everything else remains the same and in the same positions and states and the typical blank flash in page transitions disappears. History API works fine when you click on back/forward buttons, just change the browser URL but no page reload is done, this URL change can be detected by JavaScript code and custom behavior can be executed to bring the current page to the required back or forward state with no new page load.

The only caveat of History API is browser support, some old browsers like IE until v10 do not support this specification. This is not a problem, this tutorial shows how we can run the same website in browsers with no History API support just accepting conventional page navigation for fundamental states in these old browsers. In summary if you want pure SPI SEO compatible on virtually any browser use hashgbangs, if you want perfect SPI SEO compatible use History API as shown in this tutorial accepting the experience is not the best (page based) in old browsers (going to disappear anytime soon).


SPI, SEO compatiblity and History API


SPI SEO compatiblity is really easy using History API (and ItsNat), using History API we can change the URL of the current page with no reload, period, by this way end users "see" the browser URL changing and the page content changing in the same time, but the content changed can be done with partial changed drived by an AJAX event instead of conventional page loading. End users just feel how much the experience is improved (better performance, no blank flash when switching pages...). Because the new URL is pretty and conventional (no hashbangs are used), it can be bookmarked, if you are able to load the correct initial page when a concrete URL is manually written in your browser, everything is done, no _escaped_fragment_ trick is necessary, web crawlers see your site as a conventional paged site.


Web application set-up


ItsNat does not require special set up or application servers, any servlet container supporting Java 1.6 or upper is enough. Use your preferred IDE to create an empty ItsNat web application, this tutorial uses spistfulhsapitut as the name of the web application.


Creating the ItsNat servlet


Create a servlet as explained in stateful hashbang tutorial.

According to this setup the URL accessing our servlet is (8080 is supposed):

http://localhost:8080/spistfulhsapitut/servlet

Because our web site is SPI we would like a prettier URL like

http://localhost:8080/spistfulhsapitut/

In practice states are going to be defined in URL following this pattern:

http://localhost:8080/spistfulhsapitut/somestate

We need to map /somestate to the servlet /servlet:

Yes this is a bit tedious, in this example we are going to add a fixed prefix /site:

http://localhost:8080/spistfulhsapitut/site/somestate

By using this prefix we only need to register one mapping:

This is the final web.xml:

Also add a simple index.jsp with this content:

"overview" will be the default state.

Now replace the generated code of the servlet class with this code:

Take a look to the convention "overview-popup", in History API examples the character - will be used to show a state-substate, the character - is prettier in conventional URLs than the character . used in hashbangs ("overview.popup").

The classes SPITutGlobalEventListener, SPITutGlobalLoadRequestListener, SPITutMainDocument, SPITutMainLoadRequestListener,SPITutStateDetail,SPITutStateOverview,SPITutStateOverviewPopup. are basically the same as stateful hashbang counterparts, almost only states now named using - like "overview-popup" instead of . ("overview.popup").


Main page processing


Returning to the servlet:

This call registers with the name "main" the page template file main.html (saved in WEB-INF/pages/):

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:itsnat="http://itsnat.org/itsnat">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="expires" content="Wed, 1 Dec 1997 03:01:00 GMT" />
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
    <title id="titleId" itsnat:nocache="true">Tutorial: Single Page Interface STATEFUL SEO Compatible Web Site With ItsNat Using History API
    <link rel="stylesheet" type="text/css" href="../css/style.css" />
    <script type="text/javascript" src="../js/spi_hsapi.js?timestamp=2015-08-18_01"></script>
    <script type="text/javascript">
    function setState(name)
    {
        if (typeof document.getItsNatDoc == "undefined") return; // Too soon, page is not fully loaded
        var itsNatDoc = document.getItsNatDoc();
        var evt = itsNatDoc.createUserEvent("setState");
        evt.setExtraParam("name",name);
        itsNatDoc.dispatchUserEvent(null,evt);
    }
    window.spiSite.onBackForward = setState;
    </script>

</head>
<body>

    <div class="main">
    <table style="width:100%; height:100%; padding:0; margin:0;" border="0px" cellpadding="0" cellspacing="0">
    <tbody>
    <tr style="height:50px;">
        <td>
            

Tutorial: Single Page Interface STATEFUL SEO Compatible Web Site With ItsNat
Using History API

</td> </tr> <tr style="height:40px;"> <td> <table style="width:100%; margin:0; padding:0; border: #ED752A solid; border-width: 0 0 2px 0; "> <tbody> <tr class="mainMenu" itsnat:nocache="true"> <td id="menuOpOverviewId"> Overview </td> <td id="menuOpDetailId"> Detail </td> <td> </tr> </tbody> </table> </td> </tr> <tr style="height:70%; /* For MSIE */"> <td id="contentParentId" itsnat:nocache="true" style="padding:20px; vertical-align:super;" > </td> </tr> <tr style="height:50px"> <td style="border-top: 1px solid black; text-align:center;"> SOME FOOTER </td> </tr> </tbody> </table> </div> <iframe id="googleAnalyticsId" itsnat:nocache="true" src="?ganalyt_st=" style="display:none;" ></iframe> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-2924757-6', 'auto'); ga('send', 'pageview'); </script> </body> </html>

This template is very similar to the stateful hashbang example, but there are some important differences (beyond the title):

    ...
    <link rel="stylesheet" type="text/css" href="../css/style.css" />
    <script type="text/javascript" src="../js/spi_hsapi.js?timestamp=2015-08-18_01">
    ...

                    <td id="menuOpOverviewId">
                        Overview
                    </td>
                    <td id="menuOpDetailId">
                        Detail
                    </td>
    ...

Now the base path is http://localhost:8080/spistfulhsapitut/site/, this is the reason of "../css/style.css" and ="../js/spi_hsapi.js".

The JavaScript part of the SPI mini-framework for History API (stateful or stateless) is spi_hsapi.js, this is the source code:

Take a look to the code using History API like window.history.pushState(null, null, url2); or window.addEventListener("popstate", func, false);

Finally take a look to this dual link:

                    <td id="menuOpOverviewId">
                        Overview
                    </td>

As you can see, the href attribute is very simple, when JavaScript is ignored (crawlers) this link just adds the state to the URL base (which ends with "/site/").

Back to the servlet we also register a load listener for the main template:

The SPITutMainLoadRequestListener class is very similar to the stateful hashbang example, but we are now using the "-" separator:

A new SPITutMainDocument instance is created per call (load request), this instance holds an ItsNatHTMLDocument object which represents the client document (page) being loaded as usual.

The class SPITutMainDocument inherits from SPIStfulHsapiMainDocument the main class of the mini-framework to create SPI SEO compatible stateful based on history api web sites under the package org.itsnat.spistlfulhsapi.

Again we are using a mini-framework in this tutorial:

  1. org.itsnat.spi: generic classes, same as all other SPI web site tutorials

    Classes: SPIMainDocumentConfig, SPIMainDocument, SPIState, SPIStateDescriptor

  2. org.itsnat.spistful: stateful specific, already seen in stateful hashbang tutorial

    Classes: SPIStfulMainDocument, SPIStfulState.

  3. org.itsnat.spistfulhsapi: stateful and history api processing specific

    Classes: SPIStfulHsapiMainDocument

We are not going to explain the classes of the packages org.itsnat.spi and org.itsnat.spistful because they are the same as seen in stateful hashbang tutorial and already explained.


Main page processing and History API


Time to know how to manage the History API.

The package org.itsnat.spistfulhsapi has only one class SPIStfulHsapiMainDocument, this class inherits from SPIStfulMainDocument and specifies how to manage history api in this stateful context.

Obtaining the specified state present in the end of the URL on load time is really easy, no need of _escaped_fragment_ stuff like in hashbangs.

This is the first time we use the JavaScript library spi_hsapi.js, this is the source code:

Code is similar to spi_hashbang.js in this case we look for the state in the end of the URL after the last character "/" and History API is used to change the URL without reloading (pushState) and to manage back/forward buttons that is manual history navigation in general (popstate event):

If History API is not supported (old browsers), conventional page navigation is used:


Infrastructure of fundamental states


Now is the time to deep inside a concrete example using our mini-framework. We must to define the fundamental states being used as examples in this SPI web site.

This is the source code of the concrete SPITutMainDocument inherited from SPIStfulHsapiMainDocument:

Code is basically the same as SPITutMainDocument of the stateful hashbang example, the main differente is the use of "-" separator instead "." like in hashbangs.

All other classes of package org.itsnat.spistfulhsapitut are the same as the stateful hashbang example, again now the "-" separator is used.


Conclusion


This tutorial has shown a generic example of how to build SPI stateful using History API web sites with ItsNat similar to page based counterparts without sacrificing the typical features of the page paradigm like bookmarking, SEO, JavaScript disabled, Back/Forward buttons (history navigation), page visit counters etc. Use the mini-framework to build your SPI sites using this approach if you want.


Download, Online Demo and Links


See running online (try to clear cookies to check there is no need of keep client state in server)

Download source code in GitHub.




Terms of Use Privacy Statement Contributor Agreement Add to deli.cio.us Single Page Interface logo ItsNat logo Innowhere logo