How do I create multi-page applications with Meteor?

I am new to Javascript and just started fiddling around with Meteor out of curiosity. What really surprises me, is that it seems that all HTML content gets combined into a single page.

I suspect there is a way to introduce some handling of URLs directing to special pages. It seems that the "todo" example is capable of doing this via some kind of Router class. Is that the "canonical" way of URL handling?

Assuming I can handle URLs, how would I structure my HTML code to display separate pages? In my case they could each have completely separate sets of data, so no HTML code needs to be shared at all.


ANSWERS:


Jon Gold's answer used to be correct, but as of Meteor 0.5.4:

Work has now shifted to Iron Router. Please consider using IR instead of Router on new projects!

Thus, the current "canonical" way to do this is probably to use IronRouter.


As far as I am aware, there is currently no out of the box way to do this.

What I suggest to do, is to use Backbone.js smart package. Backbone.js comes with the push-state Router, and if the user's browser doesn't support that it will fallback to hash urls.

In your meteor app directory type this meteor add backbone.

Then somewhere in your client-side code create a Backbone.js Router like so:

var Router = Backbone.Router.extend({
  routes: {
    "":                 "main", //this will be http://your_domain/
    "help":             "help"  // http://your_domain/help
  },

  main: function() {
    // Your homepage code
    // for example: Session.set('currentPage', 'homePage');
  },

  help: function() {
    // Help page
  }
});
var app = new Router;
Meteor.startup(function () {
  Backbone.history.start({pushState: true});
});

Then somewhere in your Handlebars template, you can create a helper that will render a page based on the value set in Session's "currentPage".

You can find more information about backbone.js router here:

Also relevant information on how to create a Handlebars helper method in Metoer here:

Hope this helps.


Meteor-Router makes this really easy. I've been using it in some apps I've been building with Telescope as a good reference. Have a look at Telescope's router.js

To use it…

mrt add router

In client/router.js:

Meteor.Router.add({
  '/news': 'news', // renders template 'news'

  '/about': function() {
    if (Session.get('aboutUs')) {
      return 'aboutUs'; //renders template 'aboutUs'
    } else {
      return 'aboutThem'; //renders template 'aboutThem'
    }
  },

  '*': 'not_found'
});

In your template…

<body>{{renderPage}}</body>

I found the same problem. When the code gets bigger it is difficult to keep the code clean.

Here goes my approach to this problem:

I separate the different html pages as I would do with another web framework. There is an index.html where I store the root html page. And then for each big functional part I create a different template and place it in one different html. Meteor then merges them all. Finally I create a session variable called operation where I define what to show at each time.

Here goes a simple example

index.html

<head>
  <title>My app name</title>
</head>

<body>
 {{> splash}}
 {{> user}}
 {{> debates}}
</body>

then in splash.html

<template name="splash">
    {{#if showSplash}}
      ... your splash html code goes here...
    {{/if}}
</template>

then in user.html

<template name="user">
    {{#if showUser}}
      ... your user html code goes here...
    {{/if}}
</template>

and so on ...

In the javascript code then I check when to print each template using the Session variable, like this:

Template.splash.showSplash = function(){
    return Session.get("operation") == 'showSplash';
}

Finally the Backbone Router manages this Session variable

var DebateRouter = Backbone.Router.extend({

  routes: {
    "": "showSplash",
    "user/:userId": "showUser",
    "showDebates": "showDebates",
    // ...
  },
  splash: function () {
   Session.set('operation', 'showSplash');
   this.navigate('/');
  },
  user: function (userId) {
   Session.set('operation', 'showUser');
   this.navigate('user/'+userId);
  },
  // etc...
});

I hope this pattern is helpful for other Meteor developers.


This is my hacky solution to routing :

Just put the page name as the template name en navigate to /{name}



 MORE:


 ? Preferred client side routing solution?
 ? Using routes in Express-js
 ? How can you access RouteData from the code-behind?
 ? How can I override a .svc file in my routing table?
 ? Rails Routing (root :to => ...)
 ? What is routing? Why is "routing" needed in single page web apps?
 ? difference between URL rewriting and URL routing mvc
 ? getUrlRules - switch to controller
 ? getUrlRules - switch to controller
 ? getUrlRules - switch to controller