In this world of all-singing, all-dancing client-side MV* frameworks it's easy to over complicate things. Sometimes you need to rethink the problem and use appropriate technology which does just what you need it to. For example, say I have a simple Single-Page Application (SPA) to build. Each view corresponds to a Bootstrap Nav of which the view will be loaded into a container of some sort:

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8" />
    <title>Routie &hearts; Bootstrap</title>
	<link href="css/bootstrap.min.css" rel="stylesheet" />
	<link href="css/app.css" rel="stylesheet" />
    <main class="container">
        <ul class="nav nav-tabs nav-justified" id="paging">
            <li><a href="#/home">Home</a></li>
            <li><a href="#/profile">Profile</a></li>
            <li><a href="#/messages">Messages</a></li>
        <section id="pvContent"></section>

	<!-- Templates -->
    <template data-href="/home">Home Page</template>
    <template data-href="/profile">Profile Page</template>
    <template data-href="/messages">Messages Page</template>

    <!-- Scripts -->
    <script src="js/jquery.min.js"></script>
    <script src="js/routie.min.js"></script>
    <script src="js/app.js"></script>

Enter routie. What we can do with routie is bind our hashpaths to custom behaviour. The magic happens in app.js when we bind routie to the wildcard (*) route:

// app.js
"use strict";

routie('*', function (path) {
	// Load the html from template
    var tmplContent = $('template[data-href="' + path + '"]').html();

    // If any tab is selected as active, remove active class
    $('#paging >').removeClass('active');

    // Find the li with an anchor with the path in it
    $('#paging > li > a[href="#' + path + '"]')

When a user clicks on a tab, it changes the hashpath which routie observes and loads the content of a template associated with the path. There's only one caveat: what if there's no hash when the page is loaded?

// Set default hashroute to '/home' if no hash defined
if (location.hash === '') {
    location.hash = '/home';

In just a few sweet lines of js we've got our templates being loaded into our view container without a full page refresh. You'll also notice that if you refresh the page the view previously selected will be shown, no additional complexity needed!

Let's do something a little more involved: when the user clicks on the messages  tab, we will render out a table on the left side of the view and on the right hand side will be the message content:


The client-side js is super simple:

routie('/messages/:id', function (id) {
    var messageData = [
        "Hey Sam, Is that report ready?<br/>",
        "Yo Sam,<br/><br/>Let's get crunked tomorrow night!<br/><br/>- Curly",
        "Are you interested in losing weight???"

<template data-href="/messages">
	<div class="row" style="padding:10px;">
    	<nav class="col-lg-3">
        	<ul class="list-group">
            	<li class="list-group-item">
                	<span class="badge">3</span>
                    <a href="#/messages/1">Bob Jones</a>
                <li class="list-group-item">
                	<span class="badge">1</span>
                    <a href="#/messages/2">Curly Katz</a>
                <li class="list-group-item">
                	<span class="badge">1k+</span>
                    <a href="#/messages/3">Johnny D.</a>
		<section class="col-lg-7">
        	<blockquote id="msgContent"></blockquote>

you would replace the message data array with a call to your service endpoint and update the content of the list-group dynamically.

You can find the full source for this fake-SPA on GitHub.