Codementor Events

Understanding Single Page Application

Published Jul 27, 2018

Imagine a basic web application (or website), which has four pages.

  • index.html (home page)
  • products.html
  • contacts.html
  • aboutus.html

Let each page have the same header and footer. The header will have a navigation bar to move between different pages. This requirement should sound very familiar, even for beginners. But, there are two issues in this approach.

  1. When we switch between pages, the current page is removed and a new page is loaded. And it will take one or more seconds, as the new page has to be fetched from server, and in that duration, a white screen will be displayed. It is not a good user experience.
  2. Some part of the content is common across all pages. eg: Header and Footer. It would be better if we can avoid duplicating contents. It is one of the philosophies of programming, shortly know as DRY — Don’t Repeat Yourself

Single page approach helps in solving this problem. Observe the below structure.

<style>
.page {
 display: none;
}
.page.active{
 display: block;
}
</style>

<header> ... </header>
<div>
 <section class='page home active'> ... </section>
 <section class='page contactus'> ... </section>
 <section class='page products'> ... </section>
 <section class='page aboutus'> ... </section>
</div>
<footer> ... </footer>

At any point of time, only one page will be visible. (whichever section that has an active class). The header should have the navigation menu like below.

<header>
  <ul>
    <li class="active" id="home">Home</li>
    <li id="products">Products</li>
    <li id="contactus">About Us</li>
    <li id="aboutus">Contact Us</li>
  </ul>
</header>

Of course, we need the help of javascript to add and remove classes, when the user clicks on the navigation bar.

$(function () {
  $('header li').on("click", function (e) {
    $('header li').removeClass('active');
    e.target.classList.add('active');
    $('.page').removeClass('active');
    $('.content .' + e.target.id).addClass('active');
  })
})

Above is a simple jquery to remove and add ‘active’ class on the pages and the navigation menu.

So, now we have accommodated all four pages in a single page. But we have a problem, we cannot directly call the different pages through URL like below, as they don’t exist.

[www.mywebapp.com/products](http://www.mywebapp.com/products)
[www.mywebapp.com/a](http://www.mywebapp.com/products)boutus
[www.mywebapp.com/c](http://www.mywebapp.com/products)ontactus

When I have to share a particular page, I dont have a unique url for the page. I need to tell her to go to the home page and then navigate so and so, to reach the particular page. Not cool.

HTML5 History API

The New HTML5 History API helps us to solve this problem. It has provision to change the url of the page without refreshing the whole page. I have refactored the previous javascript as below.

$(function () {
  var pageName = window.location.pathname;
  pageName = pageName.substr(pageName.lastIndexOf('/') + 1);
  getPage(pageName);
  $('header li').on("click", function (e) {
    history.pushState({}, e.target.id, '/' + e.target.id);
    getPage(e.target.id)
  })

function getPage(pageName) {
    $('header li').removeClass('active');
    $('header #' + pageName).addClass('.active');
    $('.page').removeClass('active');
    $('.content .' + pageName).addClass('active');
  }
})

It works like this. When we load the page, it checks for the page name through the API ‘window.location.pathname’ and sets the active page. As we need to call the same code while loading, and on click of navigation link, I put it in a separate function. (Remember Code reuse — DRY — Don’t Repeat Yourself)

File Server Configuration

when we fire the url ‘www.mywebapp.com/products’, the server will look for an index file present inside the products folder. But unfortunately both the folder and file don’t exist and the server will return a 404. We need to redirect all calls to the home page and this configuration needs to be added on your file server.

You can find the source code here.

Note: This is just a sample minimal exercise to demonstrate SPA. We cannot directly use this for production as we have not followed the best practices and some edge cases, like requesting a page that doesn’t exist.

Discover and read more posts from Rethna
get started
post commentsBe the first to share your opinion
Cedric Poilly
6 years ago

Thanks Rethna. Nice & simple take on SPA. Clear explanation of the core concepts of Single Page Applications.

With some more work we can achieve a fully functional listing website as an SPA. No big libraries & frameworks needed.

Show more replies