How do I create multi-page applications with Meteor?

JavascriptUrl RoutingMeteor

Javascript Problem Overview


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.

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

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: http://backbonejs.org/#Router

Also relevant information on how to create a Handlebars helper method in Metoer here: http://docs.meteor.com/#templates

Hope this helps.

Solution 3 - Javascript

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>

Solution 4 - Javascript

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.

Solution 5 - Javascript

This is my hacky solution to routing : https://gist.github.com/3221138

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarcus RiemerView Question on Stackoverflow
Solution 1 - Javascriptuser456584View Answer on Stackoverflow
Solution 2 - JavascriptnsmetaView Answer on Stackoverflow
Solution 3 - JavascriptJon GoldView Answer on Stackoverflow
Solution 4 - JavascriptCarlos MoralesView Answer on Stackoverflow
Solution 5 - JavascriptLander Van BredaView Answer on Stackoverflow