Search code examples
node.jsexpresshandlebars.jssingle-page-application

Serving HTML to build a simple SPA using Node.js/Express


I want to build a website as a Single Page Application.

For what I understand a SPA sends a single entry point to the application in the form of an HTML file.

So I would like to use Node and Express to serve the main page and to then serve HTML for the content between the header and footer that gets updated using AJAX calls when a user navigates the site.

I know how to create a restful API to serve data as JSON but not much on how to deal with the HTML parts of the SPA that are changing.

The question: how could this serving of HTML parts be implemented on the server using Node and Express (and eventually a template engine like handlebars, if it helps)?

And does it actually make sense? (A header and a footer are not much data to reload after all.)


Solution

  • You can definitely do this with node.js. First you set up an HTML template engine, for instance Swig, (but you can use others) and you configure the standard options to render html pages:

    var swig  = require('swig');
    app.set('view engine', 'html');
    app.set('view options', {
        layout: false
    });
    
    app.engine('html', swig.renderFile);
    app.set('view cache', false);
    // To disable Swig's cache, do the following:
    swig.setDefaults({ cache: false });
    app.use(express.static(__dirname + '/public'));
    

    Second you set up an endpoint which serves your main HTML page.

      app.get('/',function(req, res) {
          res.render('index');
       };
    

    Then you can create node.js endpoints which will get your data:

     app.get('/users', function(req, res) {
            // Do database stuff here
            res.status(200).send(results);
        }
    

    Then you set up your HTML file:

    <!DOCTYPE html>
    <html ng-app="app">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="stylesheets/bootstrap.min.css" rel="stylesheet">
    
    <title>fast MEAN</title>
    </head>
    <body ng-controller="MainController">
    <div class="col-md-12" style="background-color: #006699">
    
    </div>
    {% raw %}
    {{helloWorld}}
    
    <ng-view></ng-view>
    
    <script src="js/angular.min.js"></script>
    <script src="js/angular-route.min.js"></script>
    <script src="app.js"></script>
    
    {% endraw %}
    </body>
    </html>
    

    Where everything outside of {% raw %} and {% endraw %} will be rendered with data using the node/swig template data, and everything inside those tags can be rendered with whatever framework you are using inside (jquery, angular, react) etc.

    An example of this simple single page application is on my github, there's one version for angular and one for react. Hope that helps.

    https://github.com/coguy450/fastMEAN