Multiple Meteor JS apps on the same domain, under virtual directories

This setup will work whether you want to host multiple Meteor apps on the same domain, or use a reverse proxy for multiple backends, one of which is Meteor JS.

Recently, we were looking into adding new features to illustreets, such as a content management system (preferably not one built in JavaScript… just yet). Subdomains were not an option, mostly due to users being familiar already with the app’s location, and also because we wanted to have the CMS controlling the first page, with the Meteor JS app (illustreets’ explorer) set to look like it is hosted in a subdirectory.

For a setup like this one, a reverse proxy is the first option you can think of. Say, you’ll be proxying /* to the CMS, whilst /[your-app-route] will be forwarded to where your Meteor JS is hosted. Yet, a Meteor app will look for its assets (images, JS files, and CSS) relative to the root ‘/’ and those are all proxied to the CMS since they fall under the /* rule. You’ll get 404 codes for all of them and the app will fail to load.

The solution is relatively simple, thanks to a change in Meteor’s code starting with version 0.6.5: the ROOT_URL environment variable may now have a path segment. According to the docs, this allows serving multiple Meteor apps on the same domain: http://example.com/app1, http://example.com/app2, etc. Do not add a trailing slash (‘/’) at the end.

We are hosting with Modulus, which, as far as we know, is the best (and maybe to date it’s still the only one available) commercial application platform that officially supports Meteor JS – check the demeteorizer. Changing the ROOT_URL environment variable was as easy as typing a URL in an input box. So, if you have, let’s say two apps, start two projects on Modulus, set the ROOT_URL for each one under ‘Environment Variables’ in the administration panel, and then add your naked domain (the one which you point at Modulus) for both apps under ‘Domains’.

That’s it!

…Or actually not, if you use the Backbone router in your app, and care about Internet Explorer 9. Because this hopefully-soon-to-be-extinct IE version does not support history.pushState(), Backbone has to use the hashbang, which in turn will redirect to the homepage. The result is that one of the apps will never be accessible. One solution is to mirror the requested page path in the hash. In your Meteor JS app add the following code when you initialise the router (credit twalker):

var homePage = "/";

if (!(window.history && window.history.pushState)) {

    window.location.hash = window.location.pathname.replace(homePage, '');

    homePage = window.location.pathname;

}

 

Router = new yourAppRouterName;

Backbone.history.start({

    pushState: true,

    root: homePage

});

Good luck!

About Manuel Timita

Passionate about both human and IT systems. More curious than a cat, yet hoping to dodge its proverbial fate for a while.
This entry was posted in Hacks, illustreets and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>