Run Backbone.js apps on a Node.js server
Single-page apps are great for interactivity, but they typically face problems with SEO, accessibility and bookmarking, due to the fact that their pages do not exist anywhere as externally accessible resources.
This means that that the HTML that is dynamically generated on the server-side exactly mirrors the DOM structure created by the client side code. All the URL routes within the app are faithfully duplicated, and the content at each URL is identical to the content that is generated on the client-side when the user navigates to that URL route within the app.
The best thing about this is that with Doppelganger, you get all these benefits without needing to perform any modifications whatsoever to the client-side code, so you can be up and running within minutes.
Doppelganger takes a Backbone.js app, and instantiates it 'behind the scenes' on the Node.js server. This gives the server a live copy of the client-side app to work with.
When a request is made to the server, the following steps are typically carried out:
Backbone.history.navigate()method (or if no matching routes are found, the server responds appropriately)
These steps mean that with minimal effort, the single-page app will now be fully accessible without relying on any client-side scripting.
The project at https://github.com/timkendrick/doppelganger-examples provides a demonstration of Doppelganger in action.
View the source of pages generated by the Doppelganger server to see the HTML that has been dynamically inserted on the server-side.
# Install the latest version of Doppelganger using NPMnpm install doppelganger
The main Doppelganger class is packaged as a CommonJS module, so once it is installed you can use
require() to use it in another module:
var Doppelganger = ;// Instantiate the app, passing in the base HTML and the path to the Require.js config filevar appInstance = fs 'js/config.js';// Initialise the app instance, passing a callback that is invoked when initialisation is completeappInstance;
var routeExists = appInstance;
var html = appInstance;
// This assumes 'app' and 'router' are AMD modules defined within the Backbone appappInstance;
var mainAppInstance = fs 'main/js/config.js' 'main';var faqAppInstance = fs 'faq/js/config.js' 'faq';mainAppInstance
require.config()call, in order to initialise Require.js correctly
"backbone"in the Require.js config file
historywill not be set. Avoid writing code that depends on the browser environment (although you do have access to jQuery for DOM manipulation, see below)
Backboneglobal variables will not be set. These should instead be accessed using Require.js (e.g. by listing
"jquery"amongst a module's dependencies - this is good practice anyway).