The dream. A single page app whose initial HTML content is served from the server.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib
.gitignore
README.md
api.js
client.js
home.jade
home.js
item.jade
item.js
layout.jade
package.json
server.js

README.md

Dual page app

Getting started

server.js

var app = require('express')()
var dual = require('./lib/dual')(app)
var post = require('./post')

// Setup blog post route for the server
post(dual)

app.listen(3000) // Start app

client.js

var page = require('page')
var dual = require('./lib/dual')(page)
var post = require('./post')

// Setup blog post route for the client
post(dual)

page() // Start app

post.js

var tpl = require('./post.jade')

module.exports = function (dual) {
  // Attach to /post/:id
  dual('/post/:id', render, init)

  // Render the page
  function render (ctx, cb) {
    var postId = ctx.params.id
    // Do async IO, eventually call cb with rendered HTML
    cb(null, tpl())
  }

  // Initialisation for the client
  function init (ctx) {
    var link = document.querySelector('a[href="#"]')

    link.addEventListener('click', function (e) {
      e.preventDefault()
      dual.page('/post/138')
    })
  }
}

dual components

dualRoute(<appOrPage>, <path>, <handler>)

Create a GET request route in an express or page.js app.

dualHandler(<render>, <init>)

Create a route handler function for GET request. It's assumed in the browser that the handler is for a page.js route and on the server it's for an express route.

The render function is passed ctx/req (depending on browser/server environment) and a callback. Once rendered it should call the callback with the rendered html. e.g.

function render (ctx, cb) {
  var itemId = ctx.params.itemId // URL params
  // Get data for template...
  cb(null, '<div>' + itemId + '</div>')
}

The rendered HTML is either sent back from the server, or it replaces the page <body> depending on environment.

The init function is called by the handler after rendering (client side only).

Please see https://github.com/tableflip/dual-page-app/blob/master/item.js for an example.