{"id":7221,"date":"2016-12-11T16:04:20","date_gmt":"2016-12-11T20:04:20","guid":{"rendered":"http:\/\/www.useragentman.com\/blog\/?p=7221"},"modified":"2016-12-15T14:55:07","modified_gmt":"2016-12-15T18:55:07","slug":"making-framework-agnostic-isomorphic-web-applications-with-query-strings-and-html5-pushstate","status":"publish","type":"post","link":"https:\/\/www.useragentman.com\/blog\/2016\/12\/11\/making-framework-agnostic-isomorphic-web-applications-with-query-strings-and-html5-pushstate\/","title":{"rendered":"Making Framework Agnostic Isomorphic Web Applications with Query Strings and HTML5 pushState"},"content":{"rendered":"\r\n<div class=\"image-container\">\r\n<!--\r\n  *\r\n  * Note: The widths here are a result of the two break points (360, 768),\r\n  * the desktop max-width of an image (835).  We then took all of these\r\n  * numbers and multiplied by two for a retina display.\r\n  * \r\n  * The conditional comments are there in case IE9 is visiting this site,\r\n  * since it has a problem with <picture>.\r\n  * \t\r\n  * We don\"t use picturefill, because all modern browsers can handle this\r\n  * (yay!)\r\n  * \r\n  * We removed the JXR renditions, because they weren\"t as good as the MOZ\r\n  * JPEG ones. \r\n  *\r\n  * Command that generated this page and assoicated images:\r\n  * html5ImageConverter.sh --jxr-nconvert --jpg-quals=33 --webp-quals=30 --jp2-rates=0.39 --sizes=360\/720\/768\/835\/1536\/1670 --no-png --use-mozjpeg --jxr-quals=1 \/images\/7221\/blog-post.png \r\n  *\r\n-->\r\n\r\n<picture class=\"alignnone size-full wp-image-7224 full-bleed full-width\">\r\n  <!--[if IE 9]><video style=\"display: none;\"><![endif]-->\r\n  <source srcset=\"\/images\/7221\/blog-post-360.jxr 360w, \/images\/7221\/blog-post-720.jxr 720w, \/images\/7221\/blog-post-768.jxr 768w, \/images\/7221\/blog-post-835.jxr 835w, \/images\/7221\/blog-post-1536.jxr 1536w, \/images\/7221\/blog-post-1670.jxr 1670w\" type=\"image\/vnd.ms-photo\">\r\n  <source srcset=\"\/images\/7221\/blog-post-360.jp2 360w, \/images\/7221\/blog-post-720.jp2 720w, \/images\/7221\/blog-post-768.jp2 768w, \/images\/7221\/blog-post-835.jp2 835w, \/images\/7221\/blog-post-1536.jp2 1536w, \/images\/7221\/blog-post-1670.jp2 1670w\" type=\"image\/jp2\">\r\n  <source srcset=\"\/images\/7221\/blog-post-360.webp 360w, \/images\/7221\/blog-post-720.webp 720w, \/images\/7221\/blog-post-768.webp 768w, \/images\/7221\/blog-post-835.webp 835w, \/images\/7221\/blog-post-1536.webp 1536w, \/images\/7221\/blog-post-1670.webp 1670w\" type=\"image\/webp\">\r\n  \r\n  <!--[if IE 9]><\/video><![endif]-->\r\n  <img class=\"full-bleed full-width\" srcset=\"\/images\/7221\/blog-post-360.jpg 360w, \/images\/7221\/blog-post-720.jpg 720w, \/images\/7221\/blog-post-768.jpg 768w, \/images\/7221\/blog-post-835.jpg 835w, \/images\/7221\/blog-post-1536.jpg 1536w, \/images\/7221\/blog-post-1670.jpg 1670w\"  \/>\r\n<\/picture>\r\n\r\n<\/div>\r\n<p>With frameworks like <a href=\"https:\/\/facebook.github.io\/react\/\" title=\"React JS website\">React<\/a> in vogue today, there is a lot of HTML being rendered exclusively on the client instead of the server, where it has traditionally occured.  While this can result in some really snappy and slick interactions, there are a few issues with doing this:    <\/p>\n<ol>\n<li>They do not work when the client has JavaScript turned off.<\/li>\n<li>In low bandwidth environments, performance will be sluggish at load time if the application is JavaScript heavy, since (usually) the majority of the JavaScript needs to load before the page state can be applied to the application.  This is a huge consideration with mobile wireless connections, where you cannot guarantee a great signal all the time.<\/li>\n<li>Sharing that state of a &#8220;single page application&#8221; via social media\/email\/instant messaging platforms can be problematic <strong>unless the URL can change when the state changes<\/strong>.\n<\/ol>\n<p>To handle the first two issues, <strong>the first-render of the application should be done by the server instead of the client.<\/strong>  This will allow users to see the page data immediately while the page loads all the assets, increasing the performance of the page at load time. Also, as the state of the page changes, the URL should also change.  If the user wants to share that change, then it&#8217;s easy as sharing that URL.  And since the first-render of that page will be done by the server, you can program the server side code to have the application give appropriate <a href=\"https:\/\/developers.facebook.com\/docs\/sharing\/webmasters\" title=\"Open Graph information from Facebook.\">Facebook Open Graph<\/a> and <a href=\"https:\/\/dev.twitter.com\/cards\/markup\" title=\"Twitter Card meta information resource from Twitter\">Twitter Card<\/a> meta tag information on first load that reflects that change to social media sites to make sharing nicer.<\/p>\n<p>When HTML5 single page applications first became popular a while back, we hit a snag &mdash; we couldn&#8217;t change the URL of the application without causing a browser refresh.  In order to work around this, many JavaScript routing frameworks (like Backbone) would change the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fragment_identifier\" title=\"Wikipedia page for Fragment Identifier.\">URL hash<\/a> of the page in order to maintain state.  This worked, but at a cost of sharing the state &mdash; social media sites would not be able to know the state of the application since the <a href=\"http:\/\/stackoverflow.com\/questions\/940905\/can-i-read-the-hash-portion-of-the-url-on-my-server-side-application-php-ruby\" title=\"Stack Overflow page, 'Can I read the hash portion of the URL on my server-side application'\">URL hash is never sent to the server via HTTP<\/a>.  Furthermore, <a href=\"https:\/\/coderwall.com\/p\/gqqmdq\/fragment-identifiers-and-the-facebook-like-button\" title=\"Coderwall article 'Fragment Identifiers and the Facebook Like Button'\">Social Media platforms like Facebook cannot use Fragment Identifiers to distinguish different states of an application<\/a>, which causes issues if you want Facebook users to be able to &#8220;Like&#8221; specific states of an application (e.g. the photo-gallery section of the application vs. other parts of the page).<\/p>\n<p>Now, however, we can use HTML5 <a href=\"http:\/\/caniuse.com\/#search=pushState\">Session Management<\/a> to change the browser&#8217;s URL within a single page web application without the browser going to the server to load the page for that URL.  Furthermore, when the user clicks the back button, this Session Management API can be used to ensure that state of the page for that URL can also be rendered without a full server page load.  I took this a step further and wrote <a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\">progressive-pushstate<\/a>, a JavaScript library which parses the data from a query string and sets this as the application&#8217;s <code>history.state<\/code> (the JavaScript object that HTML5 Session Management uses to keep state).  Links and forms on the page that change the document&#8217;s query string can be rendered by JavaScript the same way they would be rendered if that URL and query string were requested by the web server.  This also allows us to change the query string if form elements are changed without hitting the submit button.<\/p>\n<p><a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\" class=\"exampleLink\">Go to the progressive-pushstate GitHub page<\/a><\/p>\n<p>If you are confused about the power of this, let&#8217;s look at some simple examples.<\/p>\n<h2>Example 1: A Simple Mobile\/Desktop Navigation System<\/h2>\n<p>Let&#8217;s say you have to build a website that uses a <code>&lt;select&gt;<\/code> box &#8220;hamburger&#8221; menu in the mobile breakpoint, but a traditional &#8220;list of links&#8221; menu for the larger breakpoints: <\/p>\n\r\n<table class=\"dataTable noDataPadding\">\r\n<caption class=\"visually-hidden\">This table contains screenshots of a web page that uses a select-box hamburger menu in the mobile breakpoint, and a traditional nav bar for larger breakpoints<\/caption>\r\n<thead>\r\n<tr><th>Mobile Breakpoint<\/th><th>Desktop Breakpoint<\/th><\/tr>\r\n<\/thead>\r\n<tbody>\r\n<tr>\r\n<td>\r\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/11\/example-2-mobile_sm.jpg\" alt=\"screenshot of desktop version of video game demo\" width=\"383\" height=\"639\" class=\"alignnone size-full wp-image-7302\" \/>\r\n<\/td>\r\n<td>\r\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/11\/example-2-desktop_sm.jpg\" alt=\"screenshot of desktop version of video game demo\" width=\"300\" height=\"229\" class=\"alignnone size-medium wp-image-7301\" \/>\r\n<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n<p><a class=\"exampleLink\" href=\"http:\/\/useragentman.com\/examples\/progressive-pushstate\/examples\/example01.php\">Look at live version of the the hybrid nav solution using progressive-pushstate<\/a><\/p>\n<p>Let&#8217;s look briefly at the markup that makes this happen:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;nav class=\"fixedsticky\"&gt;\r\n    \r\n  &lt;!-- The CSS makes this visible only when the page is wider than 768px --&gt;\r\n  &lt;ul&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=home\"&gt;Home&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a <span class=\"hilite\">class=\"pp-link\" href=\"?f=donkey-kong\"<\/span>&gt;Donkey Kong&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=pac-man\"&gt;Pac-Man&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=robotron\"&gt;Robotron&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=tempest\"&gt;Tempest&lt;\/a&gt;&lt;\/li&gt;\r\n  &lt;\/ul&gt;\r\n\r\n  &lt;!-- The CSS makes this visible only when the page is narrower than 768px --&gt;\r\n  &lt;form <span class=\"hilite\">class=\"pp-form\" data-pp-events=\"change\"<\/span>&gt;\r\n    &lt;select name=\"f\"&gt;\r\n      &lt;option value=\"home\" selected&gt;Home&lt;\/option&gt;\r\n      &lt;option <span class=\"hilite\">value=\"donkey-kong\"<\/span>&gt;Donkey Kong&lt;\/option&gt;\r\n      &lt;option value=\"pac-man\"&gt;Pac-Man&lt;\/option&gt;\r\n      &lt;option value=\"robotron\"&gt;Robotron&lt;\/option&gt;\r\n      &lt;option value=\"tempest\"&gt;Tempest&lt;\/option&gt;\r\n    &lt;\/select&gt;\r\n\r\n  &lt;\/form&gt;\r\n&lt;\/nav&gt;\r\n\r\n&lt;script src=\"\/path\/to\/progressive-pushstate.js\"&gt;&lt;\/script&gt;  \r\n&lt;!-- not needed for progressive-pushstate, but used in page code --&gt;\r\n&lt;script src=\"\/path\/to\/jquery-3.1.1.min.js\"&gt;&lt;\/script&gt;\r\n&lt;script src=\"\/path\/to\/example02.js\"&gt;&lt;\/script&gt;\r\n\r\n<\/pre>\n<\/blockquote>\n<p>If you take a look at the navigation markup, you will see that the links will submit a query string that would be identical if the form were to submit.  Since the links have a class of <code>pp-link<\/code>, progressive-pushstate will know to override the browser&#8217;s default behaviour and handle the links. Since the form has a class of <code>pp-form<\/code> and has <code>data-pp-events<\/code> set to <code>\"change\"<\/code>, progressive-pushstate knows that it must fire when any of its fields change.<\/p>\n<p>So, how does progressive-pushstate handle the link behaviour?  In example02.js, you will see the following code:<\/p>\n<blockquote class=\"code\">\n<pre>\r\nvar example1 = new function () {\r\n  \r\n  \/\/ Use me to avoid using .bind() all over the place.\r\n  var me = this;\r\n  \r\n  me.init = function () {\r\n    pp.init(me.popstateEvent);\r\n  };\r\n  \r\n  me.popstateEvent = function(e) {\r\n    currentState = e.state;\r\n    \r\n    \/*\r\n     * At this point, `currentState.f` will be set to whatever value `f` is in\r\n     * the query string.\r\n     *\/\r\n    \r\n    .\r\n    .\r\n    .\r\n    \/\/ rest of the logic is here.\r\n  }\r\n}\r\n\r\nexample1.init();\r\n<\/pre>\n<\/blockquote>\n<p>The <code>init()<\/code> method calls <code>pp.init(me.popstateEvent)<\/code>, which initializes progressive-pushstate so that <code>pp-link<\/code> links and <code>pp-form<\/code> forms will be handled by the script. When these links and forms are used, progressive-pushstate will convert the resultant query string  to a JavaScript object and set it as the pushState for that URL.  It will then call example01.js&#8217;s <code>popstateEvent()<\/code>, which will change the contents of the main part of the page by grabbing an HTML fragment that corresponds to that page (for the sake of brevity, this logic is not shown in this article, but if you want, please take a look at the <a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\/blob\/master\/examples\/js\/example01.js\">full source of example01.js<\/a> to understand how it works).  Note that the `popstateEvent()` method uses <code>e.state<\/code> to find out the state of the page &#8230; this is the pushState object we mentioned earlier.<\/p>\n<p>There is one thing I did gloss over here &mdash; if JavaScript is turned off (or if the browser doesn&#8217;t support progressive-pushstate) the mobile navigation will fail to do anything when the select box value changes.  Since we want things to be bullet proof, we add this to the the mobile menu:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;nav class=\"fixedsticky\"&gt;\r\n  \r\n    &lt;!-- The CSS makes this visible only when the page is wider than 768px --&gt;\r\n    &lt;ul&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=home\"&gt;Home&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=donkey-kong\"&gt;Donkey Kong&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=pac-man\"&gt;Pac-Man&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=robotron\"&gt;Robotron&lt;\/a&gt;&lt;\/li&gt;\r\n    &lt;li&gt;&lt;a class=\"pp-link\" href=\"?f=tempest\"&gt;Tempest&lt;\/a&gt;&lt;\/li&gt;\r\n  &lt;\/ul&gt;\r\n  \r\n  &lt;!-- The CSS makes this visible only when the page is narrower than 768px --&gt;\r\n  &lt;form class=\"pp-form\" data-pp-events=\"change\"&gt;\r\n    &lt;select name=\"f\"&gt;\r\n      &lt;option value=\"home\" selected&gt;Home&lt;\/option&gt;\r\n      &lt;option value=\"donkey-kong\"&gt;Donkey Kong&lt;\/option&gt;\r\n      &lt;option value=\"pac-man\"&gt;Pac-Man&lt;\/option&gt;\r\n      &lt;option value=\"robotron\"&gt;Robotron&lt;\/option&gt;\r\n      &lt;option value=\"tempest\"&gt;Tempest&lt;\/option&gt;\r\n    &lt;\/select&gt;\r\n    \r\n<div class=\"hilite\">    &lt;!-- \r\n      * This button only appears when the library is not supported by the\r\n      * browser, or if JavaScript is turned off\r\n    --&gt;\r\n    &lt;input class=\"pp-no-support-button\" type=\"submit\" \r\n      aria-label=\"Go to page selected\" value=\"Go\" \/&gt;<\/div>\r\n    \r\n  &lt;\/form&gt;\r\n&lt;\/nav&gt;\r\n<\/pre>\n<\/blockquote>\n<p>Note the submit button with the className <code>pp-no-support-button<\/code>.  We want users to press this button if the browser doesn&#8217;t support progressive-pushstate.   This will allow the page to submit the form data the old fashioned way so that the page can generate the right HTML on the server.  If you look at the code for <a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\/blob\/master\/examples\/example01.php\">example01.php<\/a>, you will see PHP code that does this (this PHP code also does the first render of the page).<\/p>\n<p>We use the following CSS to show this button only when the browser can&#8217;t support progressive-pushstate (or when JavaScript is turned off):<\/p>\n<blockquote class=\"code\">\n<pre>\r\n.pp-no-support-button {\r\n\tdisplay: inline-block;\r\n}\r\n\r\n.pp-support .pp-no-support-button {\r\n\tdisplay: none;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>The classes <code>pp-support<\/code> is set on the <code>&lt;html&gt;<\/code> tag by progressive-pushstate when the page loads if the browser is supported by the library &mdash; if not, the library sets the <code>pp-no-support<\/code> class instead. <\/p>\n<p>These classes allow developers to give an alternative UI if the library is no supported.  These fallback features that give an expected (but not as sexy) user experience to older and JavaScript-disabled browsers are a great example of progressive enhancement, which is why I called this library <strong>progressive-<\/strong>pushstate.js<\/p>\n<p>If you use the navigation functionality in the above example to go to several pages, try hitting the back button.  You will notice it remembers history perfectly.  This is because pressing the browser history buttons (i.e. back and forward) will also invoke the <code>popstateEvent<\/code> as well.  History management happens for free!<\/p>\n<p>Let&#8217;s take a look at another example.<\/p>\n<h2>Example 2: A &#8220;Search As You Type&#8221; Page<\/h2>\n<p>Many Search Engines (including Google) will show results while the user types in a form.  Let&#8217;s look at an example that uses progressive-pushstate:<\/p>\n<p><div id=\"attachment_7315\" style=\"width: 425px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-7315\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/11\/example-3.jpg\" alt=\"Screen capture of search example\" width=\"415\" height=\"238\" class=\"size-full wp-image-7315\" srcset=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/11\/example-3.jpg 415w, https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/11\/example-3-300x172.jpg 300w\" sizes=\"auto, (max-width: 415px) 100vw, 415px\" \/><p id=\"caption-attachment-7315\" class=\"wp-caption-text\">This basic search form will go to the server while the user is typing in a search term.<\/p><\/div><\/p>\n<p><a class=\"exampleLink\" href=\"http:\/\/useragentman.com\/examples\/progressive-pushstate\/examples\/example02-form.php\">Look at live version of the search example.<\/a><\/p>\n<p>You will note that the form will do a search while the user types a search string into it.  This is because we instructed progressive-pushstate to do a search <code>oninput<\/code>:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;form class=\"pp-form\" <span class=\"hilite\">data-pp-events=\"input submit\"<\/span>&gt;\r\n  &lt;label for=\"country\"&gt;\r\n    Country: \r\n    &lt;input\r\n      autofocus\r\n      type=\"text\"\r\n      id=\"country\"\r\n      name=\"country\"\r\n      placeholder=\"Please enter in a country.\"\r\n      autocomplete=\"off\" \r\n      value=\"\"\/&gt;\r\n    &lt;\/label&gt;\r\n&lt;\/form&gt;\r\n<\/pre>\n<\/blockquote>\n<p>The library automatically throttles these submissions in order to prevent really fast typers that type 200 characters a minute from killing the web server with 200 requests a minute.  Note also that history is again baked in, so if users make mistakes or want to see previous searches, they can just press the back button.  Finally, the fallback is simple for JavaScript disabled browsers or browsers that don&#8217;t support this library &mdash; users can just hit enter to do a search.  This will cause a page refresh, but that&#8217;s okay, since the page still works as intended.<\/p>\n<h2>Example 3: A Filtered Table<\/h2>\n<p>Since I am currently working on an accessibility project with my current client, I wanted to build a page with a table that listed all the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Web_Content_Accessibility_Guidelines\">Web Content Accessibility Guidelines<\/a> with a way to filter them by principle (Perceivable, Operable, Understandable and Robust) as well as level (A, AA and AAA).<\/p>\n<p><div id=\"attachment_7341\" style=\"width: 710px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" aria-describedby=\"caption-attachment-7341\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/12\/wcag-example.jpg\" alt=\"A screen shot of the table filtering example.\" class=\"size-full wp-image-7341\" \/><p id=\"caption-attachment-7341\" class=\"wp-caption-text\">A screen shot of the table filtering example.<\/p><\/div><\/p>\n<p><a class=\"exampleLink\" href=\"http:\/\/useragentman.com\/examples\/progressive-pushstate\/examples\/example03-wcag.php\">Look at live version of filtered table example.<\/a><\/p>\n<p>Again, with a modern browser with Javascript turned on, you will see a nice animation when new rows are added to the table.  When you refresh the page, the table with the proper filters will be generated on the server side.<\/p>\n<div class=\"importantNotes\">\n<strong>Note the submit button at the end of the form.<\/strong> Unlike the previous examples, the content only changes when we submit.  This is to ensure that this page conforms to the WCAG 2.0 (specifically, <a href=\"https:\/\/www.w3.org\/TR\/UNDERSTANDING-WCAG20\/consistent-behavior-unpredictable-change.html\">3.2.2 \u2013 On Input (Level A)<\/a>.  We force progressive-pushstate to only allow state changes when the form submits.  This is done by setting the form&#8217;s <code>data-pp-events<\/code> to <code>\"submit\"<\/code><\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;form class=\"pp-form\" autocomplete=\"off\" <span class=\"hilite\">data-pp-events=\"submit\"<\/span>&gt;\r\n  .\r\n  .\r\n  .\r\n&lt;\/form&gt;\r\n<\/pre>\n<\/blockquote>\n<p>If you are using progressive-pushstate to create an accessible website that complies with this international standard, you <strong>must<\/strong> do this if you are <a href=\"https:\/\/www.w3.org\/TR\/2016\/NOTE-WCAG20-TECHS-20161007\/G80\">providing a submit button to initiate a change of context<\/a>.  Note that <a href=\"https:\/\/www.w3.org\/TR\/2008\/REC-WCAG20-20081211\/#context-changedef\">change of <em>content<\/em> is not always a change of <em>context<\/em><\/a>.\n<\/div>\n<h2>Pitfalls and Solutions to Isomorphic Applications<\/h2>\n<p>When coding isomorphic applications, developers should ensure that the client and the server both display the same data for each URL.  For example, the AJAX requests used in examples #1 and #2 return HTML.  This is the same HTML that would be inserted into the page by the server for that page&#8217;s state.  We do this by using PHP&#8217;s <code>include<\/code> to call the same PHP code that the AJAX request calls.<\/p>\n<p>The method was used in these examples for simplicity sake &mdash; however, most single page web applications that do AJAX requests return JSON that is parsed by the front-end JavaScript and translated to HTML.  If you want the same JSON payload to be parsed and translated to HTML on the server, you&#8217;d have to port that same code into whatever server side language you are using or run the same JavaScript you run on the client on the server as well.  Running JavaScript on the server is the preferable way to go since you only have to code your presentation logic once.<\/p>\n<p>Running server-side JavaScript is possible using Node, but what if you have an existing site that runs a different server-side technology?  Don&#8217;t fret! Many of them can still run JavaScript.  For example:<\/p>\n<ul>\n<li>I have worked on projects where we took <a href=\"http:\/\/olado.github.io\/doT\/index.html\">DoT templates<\/a> and ran them on the server using <a href=\"https:\/\/github.com\/erickzanardo\/dj>DoT for Java<\/a> and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Mozilla\/Projects\/Rhino\">Rhino<\/a>,a JavaScript engine that runs within the Java 6 and 7.<\/li>\n<li><a href=\"http:\/\/winterbe.com\/\">Benjamin Winterberg<\/a> has written <a href=\"http:\/\/winterbe.com\/posts\/2015\/02\/16\/isomorphic-react-webapps-on-the-jvm\/\">an interesting article on running React components on the server<\/a> using <a href=\"http:\/\/www.oracle.com\/technetwork\/articles\/java\/jf14-nashorn-2126515.html\">Nashorn<\/a> (the JavaScript engine that ships with Java 8)<\/li>\n<li>If you are using PHP, I have heard that PHP&#8217;s documentation on <a href=\"http:\/\/php.net\/manual\/en\/book.v8js.php\">V8 Javascript Engine Integration<\/a> can help devs run JavaScript within it.<\/li>\n<li>If you are really kickin&#8217; it old school, <a href=\"https:\/\/metacpan.org\/pod\/JavaScript::SpiderMonkey\">you can even run JavaScript in Perl as well.<\/a><\/li>\n<\/ul>\n<p>In short, there doesn&#8217;t seem to be a shortage of solutions of running JavaScript on a server if you can&#8217;t use Node.<\/p>\n<h2>Do I Have To Use progressive-pushstate To Make My Applications Isomorphic?<\/h2>\n<p>Not at all. Here are some other solutions excellent solutions (just to name a few):<\/p>\n<ul>\n<li>If you use React, Smashing Magazine&#8217;s has a great article, <a href=\"https:\/\/www.smashingmagazine.com\/2016\/03\/server-side-rendering-react-node-express\/\">Server-Side Rendering With React, Node And Express<\/a> (even if you don&#8217;t use React, this has a great write-up on the advantages of programming isomorphically)<\/li>\n<li><a href=\"http:\/\/redux.js.org\/docs\/recipes\/ServerRendering.html\">The Redux document on server rendering<\/a> also has a great write-up on how to do this.<\/li>\n<li>There is also a framework to <a href=\"https:\/\/github.com\/saymedia\/angularjs-server\">run AngularJS apps on the server, using NodeJS<\/a>\n<\/ul>\n<p>You will notice that all of these solutions (and a lot of others) rely on you using a specific framework.  This is why I created progressive-pushstate &mdash; I wanted something more generic, since it is not always possible to use these frameworks in every project (e.g. when you are interfacing with an existing package, when you are modifying an existing codebase, etc).  Also, I have found <strong>JavaScript packages are like opinions &mdash; everyone has one and even the most popular ones tend to change or disappear over time.<\/strong><\/p>\n<h2>Other Features of progressive-pushstate<\/h2>\n<p>There are more features to progressive-pushstate than shown in these examples. A full breakdown is available on the <a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\">progressive-pushstate github page<\/a>.<\/p>\n<h2>Planned Upcoming Features of progressive-pushstate<\/h2>\n<ul>\n<li>One thing I would think would be great is if instead of using standard query strings (e.g. <code>http:\/\/domain.com\/page?a=x&#038;b=y&#038;c=z<\/code>) developers could use directories slugs instead, like Expression Engine does (e.g. <code>http:\/\/domain.com\/page\/a\/x\/b\/y\/c\/z<\/code>).  I did not do this in the first release because the work I do usually involves forms, and using query strings is the default way forms send information to the browser, so it just made sense to do it that way.<\/li>\n<li>Another feature I would love to add is to ensure we can progressive-pushstate&#8217;s data into a separate property in the pushState. That is to say, instead of having <code>http:\/\/domain.com\/page?a=x&#038;b=y&#038;c=z<\/code> resulting in a pushState of this:<br \/>\n<blockquote class=\"code\">\n<pre>\r\n{\r\n  a: 'x',\r\n  b: 'y',\r\n  c: 'z'\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>it can result of a pushState of this:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n{\r\n  pp: {\r\n    a: 'x',\r\n    b: 'y',\r\n    c: 'z'\r\n  }\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>The advantage for doing this, in my opinion, is to allow progressive-pushstate to play nice with other JavaScript libraries that work with the HTML5 Session API.\n<\/li>\n<\/ul>\n<p>I definitely want to add both of these features in a not-so-distant future release when I get some extra time.  If anyone else  would like to work on these or any other improvement, please feel free to send me a pull request.  Alternatively, if you don&#8217;t have the time to contribute would like to request a different features for this library, please feel to leave a comment below or on the <a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\/issues\">issue page for progressive-pushstate<\/a>.<\/p>\n<h2>Browser Support for progressive-pushstate<\/h2>\n<p>It works in all modern browsers (including many of the older browsers in current use, like IE10+ and Android Browser 4.3+) and if you ensure the server side can do the render all the states without JavaScript, the fallback for unsupported browsers (like Opera Mini or IE <= 9) is to let the server render the page.\n\n<a href=\"https:\/\/github.com\/zoltan-dulac\/progressive-pushstate\" class=\"exampleLink\">Go to the progressive-pushstate GitHub page<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2016\/12\/blog-post-1536-thumb.jpg\" \/>  Do you  want the state of a web page to be rendered by both the client and the server side?  Is having the state of a JavaScript rendered web page to be controlled by the page&#8217;s query string important to you? Is important for you to ensure that your page&#8217;s state can be shared correctly via email and social media? If you want all of this without being tied into any specific framework (e.g. React, jQuery, Angular, etc) and done using progressive-enhancement, read on.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[109,118,145,35,200],"tags":[204,203,202,201,164,207,208,229,205,206],"class_list":["post-7221","post","type-post","status-publish","format-standard","hentry","category-events","category-events-html5","category-forms-html5","category-html5","category-pushstate","tag-isomorphic","tag-isomorphic-applications","tag-isomorphic-web","tag-isomorphic-web-applications","tag-javascript-2","tag-node","tag-php","tag-pushstate","tag-query-strings","tag-server-side-javascript"],"_links":{"self":[{"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7221","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/comments?post=7221"}],"version-history":[{"count":125,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7221\/revisions"}],"predecessor-version":[{"id":7419,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/7221\/revisions\/7419"}],"wp:attachment":[{"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/media?parent=7221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/categories?post=7221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/tags?post=7221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}