# Remove original FlowRouter
meteor remove kadira:flow-router
# Install FR-Extra
meteor add ostrio:flow-router-extra
Note: This package is meant to replace original FlowRouter, kadira:flow-router
should be removed to avoid interference and unexpected behavior.
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
// Create index route
FlowRouter.route('/', {
name: 'index',
action() {
// Do something here
// After route is followed
this.render('templateName');
}
});
// Create 404 route (catch-all)
FlowRouter.route('*', {
action() {
// Show 404 error page
this.render('notFound');
}
});
Introduced in v3.7.1
By default if same template is rendered when user navigates to a different route, including parameters or query-string change/update rendering engine will smoothly only update template's data. In case if you wish to force full template rendering executing all hooks and callbacks use { conf: { forceReRender: true } }
, like:
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
import '/imports/client/layout/layout.js';
FlowRouter.route('/item/:_id', {
name: 'item',
conf: {
// without this option template won't be re-rendered
// upon navigation between different "item" routes
// e.g. when navigating from `/item/1` to `/item/2`
forceReRender: true
},
waitOn() {
return import('/imports/client/item/item.js');
},
action(params) {
this.render('layout', 'item', params);
}
});
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
// Going to: /article/article_id/article-slug
FlowRouter.route('/article/:_id/:slug', {
name: 'article',
action(params) {
// All passed parameters is available as Object:
console.log(params);
// { _id: 'article_id', slug: 'article-slug' }
// Pass params to Template's context
this.render('article', params);
},
waitOn(params) {
return Meteor.subscribe('article', params._id);
}
});
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
// Going to: /article/article_id?comment=123
FlowRouter.route('/article/:_id', {
name: 'article',
action(params, qs) {
// All passed parameters and query string
// are available as Objects:
console.log(params);
// { _id: 'article_id' }
console.log(qs);
// { comment: '123' }
// Pass params and query string to Template's context
this.render('article', _.extend(params, qs));
}
});
Note: if you're using any package which requires original FR namespace, throws an error, you can solve it with next code:
// in /lib/ directory
Package['kadira:flow-router'] = Package['ostrio:flow-router-extra'];
FlowRouter.current();
- Returns {Object}
Get the current state of the router. This API is not reactive.
If you need to watch the changes in the path simply use FlowRouter.watchPathChange()
.
// route def: /apps/:appId
// url: /apps/this-is-my-app?show=yes&color=red
const current = FlowRouter.current();
console.log(current);
// prints following object
// {
// path: "/apps/this-is-my-app?show=yes&color=red",
// params: {appId: "this-is-my-app"},
// queryParams: {show: "yes", color: "red"}
// route: {pathDef: "/apps/:appId", name: "name-of-the-route"}
// }
FlowRouter.getParam(paramName);
paramName
{String}- Returns {String}
Reactive function which you can use to get a parameter from the URL.
// route def: /apps/:appId
// url: /apps/this-is-my-app
const appId = FlowRouter.getParam('appId');
console.log(appId); // prints "this-is-my-app"
FlowRouter.getQueryParam(queryKey);
queryKey
{String}- Returns {String}
Reactive function which you can use to get a value from the query string.
// route def: /apps/:appId
// url: /apps/this-is-my-app?show=yes&color=red
const color = FlowRouter.getQueryParam('color');
console.log(color); // prints "red"
FlowRouter.getRouteName();
- Returns {String}
Use to get the name of the route reactively.
Tracker.autorun(function () {
const routeName = FlowRouter.getRouteName();
console.log('Current route name is: ', routeName);
});
.go(path, params, qs)
path
{String} - Path or Route's nameparams
{Object} - Serialized route parameters,{ _id: 'str' }
qs
{Object} - Serialized query string,{ key: 'val' }
- Returns {true}
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
FlowRouter.route('/blog', { name: 'blog' /* ... */ });
FlowRouter.route('/blog/:_id', { name: 'blogPost' /* ... */ });
FlowRouter.go('/blog'); // <-- by path - /blog/
FlowRouter.go('blog'); // <-- by Route's name - /blog/
FlowRouter.go('blogPost', { _id: 'post_id' }); // /blog/post_id
FlowRouter.go('blogPost', { _id: 'post_id' }, { commentId: '123' }); // /blog/post_id?commentId=123
Use group routes for better route organization.
.group(options)
options
{Object} - [Optional]options.name
{String} - [Optional] Route's nameoptions.prefix
{String} - [Optional] Route prefixoptions[prop-name]
{Any} - [Optional] Any property which will be available inside route calloptions[hook-name]
{Function} - [Optional] See all available hooks- Returns {Group}
const adminRoutes = FlowRouter.group({
prefix: '/admin',
name: 'admin',
triggersEnter: [(context, redirect) => {
console.log('running group triggers');
}]
});
// handling /admin/ route
adminRoutes.route('/', {
name: 'adminIndex',
action() { /* ... */ }
});
// handling /admin/posts
adminRoutes.route('/posts', {
name: 'adminPosts',
action() { /* ... */ }
});
const adminRoutes = FlowRouter.group({
prefix: '/admin',
name: 'admin'
});
const superAdminRoutes = adminRoutes.group({
prefix: '/super',
name: 'superadmin'
});
// handling /admin/super/post
superAdminRoutes.route('/post', {
action() { /* ... */ }
});
FlowRouter.current().route.group.name
This can be useful for determining if the current route is in a specific group (e.g. admin, public, loggedIn) without needing to use prefixes if you don't want to. If it's a nested group, you can get the parent group's name with:
FlowRouter.current().route.group.parent.name
FlowRouter.initialize();
- Returns {void}
By default, FlowRouter initializes the routing process in a Meteor.startup()
callback. This works for most of the applications. But, some applications have custom initializations and FlowRouter needs to initialize after that.
So, that's where FlowRouter.wait()
comes to save you. You need to call it directly inside your JavaScript file. After that, whenever your app is ready call FlowRouter.initialize()
.
FlowRouter.wait();
WhenEverYourAppIsReady(() => {
FlowRouter.initialize();
});
FlowRouter.onRouteRegister(callback);
callback
{Function}- Returns {void}
This API is specially designed for add-on developers. They can listen for any registered route and add custom functionality to FlowRouter. This works on both server and client alike.
FlowRouter.onRouteRegister((route) => {
// do anything with the route object
console.log(route);
});
FlowRouter.path(path, params, qs);
path
{String} - Path or Route's nameparams
{Object} - Serialized route parameters,{ _id: 'str' }
qs
{Object} - Serialized query string,{ key: 'val' }
- Returns {String} - URI
const pathDef = '/blog/:cat/:id';
const params = { cat: 'met eor', id: 'abc' };
const queryParams = {show: 'y+e=s', color: 'black'};
const path = FlowRouter.path(pathDef, params, queryParams);
console.log(path); // --> "/blog/met%20eor/abc?show=y%2Be%3Ds&color=black"
If there are no params
or qs
, it will simply return the path as it is.
// Use dashes as separators so `/:id-:slug/` isn't translated to `id-:slug` but to `:id`-`:slug`
FlowRouter.pathRegExp = /(:[\w\(\)\\\+\*\.\?\[\]]+)+/g;
pathRegExp
{RegExp}- Default -
/(:[\w\(\)\\\+\*\.\?\[\]\-]+)+/g
Use to change the URI RegEx parser used for params
, for more info see #25.
The current behavior of FlowRouter.getQueryParam("...")
and FlowRouter.current().queryParams
is to double-decode query params, but this can cause issues when, for example, you want to pass a URL with its own query parameters as a URI component, such as in an OAuth flow or a redirect after login.
To solve this, you can set this option to true
to tell FlowRouter to only decode query params once.
// Allows us to pass things like encoded URLs as query params (default = false)
FlowRouter.decodeQueryParamsOnce = true;
Given the URL in the address bar:
http://localhost:3000/signin?after=%2Foauth%2Fauthorize%3Fclient_id%3D123%26redirect_uri%3Dhttps%253A%252F%252Fothersite.com%252F
If decodeQueryParamsOnce
is not set or set to false
❌ ...
FlowRouter.getQueryParam("after");
// returns: "/oauth/authorize?client_id=123"
FlowRouter.current().queryParams;
// returns: { after: "/oauth/authorize?client_id=123", redirect_uri: "https://othersite.com/" }
If decodeQueryParamsOnce
is set to true
✔️ ...
FlowRouter.getQueryParam("after");
// returns: "/oauth/authorize?client_id=123&redirect_uri=https%3A%2F%2Fothersite.com%2F"
FlowRouter.current().queryParams;
// returns: { after: "/oauth/authorize?client_id=123&redirect_uri=https%3A%2F%2Fothersite.com%2F" }
The former is no longer recommended, but to maintain compatibility with legacy apps, false
is the default value for this flag. Enabling this flag manually with true
is recommended for all new apps. For more info, see #78.
FlowRouter.refresh('layout', 'template');
layout
{String} - [required] Name of the layout templatetemplate
{String} - [required] Name of the intermediate template, simple<template>Loading...</template>
might be a good option
FlowRouter.refresh()
will force all route's rules and hooks to re-run, including subscriptions, waitOn(s) and template render.
Useful in cases where template logic depends from route's hooks, example:
in example above "yielded" template may loose data context after user login action, although user login will cause yield
template to render - data
and waitOn
hooks will not fetch new data.
Meteor.loginWithPassword({
username: '[email protected]'
}, 'password', error => {
if (error) {
/* show error */
} else {
/* If login form has its own `/login` route, redirect to root: */
if (FlowRouter._current.route.name === 'login') {
FlowRouter.go('/');
} else {
FlowRouter.refresh('_layout', '_loading');
}
}
});
Meteor.logout((error) => {
if (error) {
console.error(error);
} else {
FlowRouter.refresh('_layout', '_loading');
}
});
FlowRouter.reload();
- Returns {void}
FlowRouter routes are idempotent. That means, even if you call FlowRouter.go()
to the same URL multiple times, it only activates in the first run. This is also true for directly clicking on paths.
So, if you really need to reload the route, this is the method you want.
this.render()
method is available only inside hooks.
Note
this.render()
method is available only if application has templating
and blaze
, or blaze-html-templates
packages installed
this.render(layout, template [, data, callback])
layout
{String|Blaze.Template} - Blaze.Template instance or a name of layout template (which hasyield
)template
{String|Blaze.Template} - Blaze.Template instance or a name of template (which will be rendered into yield)data
{Object} - [Optional] Object of data context to use in template. Will be passed to bothlayout
andtemplate
callback
{Function} - [Optional] Callback triggered after template is rendered and placed into DOM. This callback has no context
this.render(template [, data, callback])
template
{String|Blaze.Template} - Blaze.Template instance or a name of template (which will be rendered intobody
element, or element defined inFlowRouter.Renderer.rootElement
)data
{Object} - [Optional] Object of data context to use in templatecallback
{Function} - [Optional] Callback triggered after template is rendered and placed into DOM. This callback has no context
- Made with animation performance in mind, all DOM interactions are wrapped into
requestAnimationFrame
- In-memory rendering (a.k.a. off-screen rendering, virtual DOM), disabled by default, can be activated with
FlowRouter.Renderer.inMemoryRendering = true;
- Settings below is experimental, targeted to reduce on-screen DOM layout reflow, speed up rendering on slower devices and Phones in first place, by moving DOM computation to off-screen (a.k.a. In-Memory DOM, Virtual DOM)
FlowRouter.Renderer.rootElement
{Function} - Function which returns root DOM element where layout will be rendered, default:document.body
FlowRouter.Renderer.inMemoryRendering
{Boolean} - Enable/Disable in-memory rendering, default:false
FlowRouter.Renderer.getMemoryElement
{Function} - Function which returns default in-memory element, default:document.createElement('div')
. Usedocument.createDocumentFragment()
to avoid extra parent elements- The default
document.createElement('div')
will cause extra wrappingdiv
element document.createDocumentFragment()
won't cause extra wrappingdiv
element but may lead to exceptions in Blaze engine, depends from your app implementation
- The default
.route(path, options)
path
{String} - Path with placeholdersoptions
{Object}options.name
{String} - Route's nameoptions[prop-name]
{Any} - [Optional] Any property which will be available inside route calloptions[hook-name]
{Function} - [Optional] See all available hooks- Returns {Route}
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
FlowRouter.route('/blog/:cat/:id', {
name: 'blogPostRoute'
})
const params = {cat: "meteor", id: "abc"};
const queryParams = {show: "yes", color: "black"};
const path = FlowRouter.path("blogPostRoute", params, queryParams);
console.log(path); // prints "/blog/meteor/abc?show=yes&color=black"
// Create 404 route (catch-all)
FlowRouter.route('*', {
action() {
// Show 404 error page
}
});
FlowRouter.setParams(params);
params
{Object} - Serialized route parameters,{ _id: 'str' }
- Returns {true}
Change the current Route's params
with the new values and re-route to the new path.
// route def: /apps/:appId
// url: /apps/this-is-my-app?show=yes&color=red
FlowRouter.setParams({appId: 'new-id'});
// Then the user will be redirected to the following path
// /apps/new-id?show=yes&color=red
FlowRouter.setQueryParams(qs);
qs
{String} - Serialized query string,{ key: 'val' }
- Returns {true}
To remove a query param set it to null
:
FlowRouter.setQueryParams({ paramToRemove: null });
FlowRouter.triggers.enter([cb1, cb2]);
FlowRouter.triggers.exit([cb1, cb2]);
// filtering
FlowRouter.triggers.enter([trackRouteEntry], {only: ["home"]});
FlowRouter.triggers.exit([trackRouteExit], {except: ["home"]});
To filter routes use only
or except
keywords.
You can't use both only
and except
at once.
FlowRouter.url(path, params, qs);
path
{String} - Path or Route's nameparams
{Object} - Serialized route parameters,{ _id: 'str' }
qs
{Object} - Serialized query string,{ key: 'val' }
- Returns {String} - Absolute URL using
Meteor.absoluteUrl
FlowRouter.wait();
- Returns {void}
By default, FlowRouter initializes the routing process in a Meteor.startup()
callback. This works for most of the applications. But, some applications have custom initializations and FlowRouter needs to initialize after that.
So, that's where FlowRouter.wait()
comes to save you. You need to call it directly inside your JavaScript file. After that, whenever your app is ready call FlowRouter.initialize()
.
FlowRouter.wait();
WhenEverYourAppIsReady(() => {
FlowRouter.initialize();
});
FlowRouter.watchPathChange();
- Returns {void}
Reactively watch the changes in the path. If you need to simply get the params
or qs
use methods like FlowRouter.getQueryParam()
.
Tracker.autorun(() => {
FlowRouter.watchPathChange();
const currentContext = FlowRouter.current();
// do something with the current context
});
FlowRouter.withReplaceState(callback);
callback
{Function}- Returns {void}
Normally, all the route changes made via APIs like FlowRouter.go
and FlowRouter.setParams()
add a URL item to the browser history. For example, run the following code:
FlowRouter.setParams({id: 'the-id-1'});
FlowRouter.setParams({id: 'the-id-2'});
FlowRouter.setParams({id: 'the-id-3'});
Now you can hit the back button of your browser two times. This is normal behavior since users may click the back button and expect to see the previous state of the app.
But sometimes, this is not something you want. You don't need to pollute the browser history. Then, you can use the following syntax.
FlowRouter.withReplaceState(() => {
FlowRouter.setParams({id: 'the-id-1'});
FlowRouter.setParams({id: 'the-id-2'});
FlowRouter.setParams({id: 'the-id-3'});
});
action(params, qs, data)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
data
{Mix} - Value returned from.data()
hook- Return: {void}
.action()
hook is triggered right after page is navigated to route, or after (exact order, if any of those is defined):
data(params, qs)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
- Return: {Mongo.Cursor|Object|[Object]|false|null|void}
.data()
is triggered right after all resources in .waitOn()
and .waitOnResources()
hooks are ready.
FlowRouter.route('/post/:_id', {
name: 'post',
waitOn(params) {
return Meteor.subscribe('post', params._id);
},
async data(params, qs) {
return await PostsCollection.findOneAsync({_id: params._id});
}
});
FlowRouter.route('/post/:_id', {
name: 'post',
action(params, qs, post) {
this.render('_layout', 'post', { post });
},
waitOn(params) {
return Meteor.subscribe('post', params._id);
},
async data(params, qs) {
return await PostsCollection.findOneAsync({_id: params._id});
}
});
<!-- in a template -->
<template name="post">
<h1>{{post.title}}</h1>
<p>{{post.text}}</p>
</template>
Returned value from data
hook, will be passed into all other hooks as third argument and to triggersEnter
hooks as fourth argument
FlowRouter.route('/post/:_id', {
name: 'post',
async data(params) {
return await PostsCollection.findOneAsync({_id: params._id});
},
triggersEnter: [(context, redirect, stop, data) => {
console.log(data);
}]
});
endWaiting()
- Called with no arguments
- Return: {void}
.endWaiting()
hook is triggered right after all resources in .waitOn()
and .waitOnResources()
hooks are ready.
onNoData(params, qs)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
- Return: {void}
.onNoData()
hook is triggered instead of .action()
in case when .data()
hook returns "falsy" value. Run any JavaScript code inside .onNoData()
hook, for example render 404 template or redirect user somewhere else.
FlowRouter.route('/post/:_id', {
name: 'post',
async data(params) {
return await PostsCollection.findOneAsync({_id: params._id});
},
async onNoData(params, qs){
await import('/imports/client/page-404.js');
this.render('_layout', '_404');
}
});
triggersEnter
is option (not actually a hook), it accepts array of Functions, each function will be called with next arguments:
context
{Route} - Output ofFlowRouter.current()
redirect
{Function} - Use to redirect to another route, same asFlowRouter.go()
methodstop
{Function} - Use to abort current route executiondata
{Mix} - Value returned from.data()
hook- Return: {void}
const scrollToTop = () => {
(window.scroll || window.scrollTo || function (){})(0, 0);
};
FlowRouter.route('/', {
name: 'index',
triggersEnter: [scrollToTop]
});
// Apply to every route:
FlowRouter.triggers.enter([scrollToTop]);
FlowRouter.route('/', {
name: 'index',
triggersEnter: [() => {
console.log('triggersEnter');
}]
});
FlowRouter.route('/', {
name: 'index',
triggersEnter: [(context, redirect) => {
redirect('/other/route');
}]
});
FlowRouter.triggers.enter([cb1, cb2]);
triggersExit
is option (not actually a hook), it accepts array of Functions, each function will be called with one argument:
context
{Route} - Output ofFlowRouter.current()
- Return: {void}
const trackRouteEntry = (context) => {
// context is the output of `FlowRouter.current()`
console.log("visit-to-home", context.queryParams);
};
const trackRouteClose = (context) => {
console.log("move-from-home", context.queryParams);
};
FlowRouter.route('/home', {
// calls just before the action
triggersEnter: [trackRouteEntry],
action() {
// do something you like
},
// calls when when we decide to move to another route
// but calls before the next route started
triggersExit: [trackRouteClose]
});
FlowRouter.triggers.exit([cb1, cb2]);
waitOn(params, qs, ready)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
ready
{Function} - Call when computation is ready using Tracker- Return: {Promise|[Promise]|Subscription|[Subscription]|Tracker|[Tracker]}
.waitOn()
hook is triggered before .action()
hook, allowing to load necessary data before rendering a template.
FlowRouter.route('/post/:_id', {
name: 'post',
waitOn(params) {
return [Meteor.subscribe('post', params._id), Meteor.subscribe('suggestedPosts', params._id)];
}
});
Use reactive data sources inside waitOn
hook. To make waitOn
rerun on reactive data changes, wrap it to Tracker.autorun
and return Tracker Computation object or an Array of Tracker Computation objects. Note: the third argument of waitOn
is ready
callback.
FlowRouter.route('/posts', {
name: 'post',
waitOn(params, qs, ready) {
return Tracker.autorun(() => {
ready(() => {
return Meteor.subscribe('posts', search.get(), page.get());
});
});
}
});
FlowRouter.route('/posts', {
name: 'post',
waitOn(params, qs, ready) {
const tracks = [];
tracks.push(Tracker.autorun(() => {
ready(() => {
return Meteor.subscribe('posts', search.get(), page.get());
});
}));
tracks.push(Tracker.autorun(() => {
ready(() => {
return Meteor.subscribe('comments', postId.get());
});
}));
return tracks;
}
});
FlowRouter.route('/posts', {
name: 'posts',
waitOn() {
return new Promise((resolve, reject) => {
loadPosts((err) => {
(err) ? reject() : resolve();
});
});
}
});
FlowRouter.route('/posts', {
name: 'posts',
waitOn() {
return [new Promise({/*..*/}), new Promise({/*..*/}), new Promise({/*..*/})];
}
});
Deprecated, since v3.12.0 Meteor.callAsync
can get called inside async data()
hook to retrieve data from a method
FlowRouter.route('/posts', {
name: 'posts',
conf: {
posts: false
},
action(params, qs, data) {
this.render('layout', 'posts', data);
},
waitOn() {
return new Promise((resolve, reject) => {
Meteor.call('posts.get', (error, posts) => {
if (error) {
reject();
} else {
// Use `conf` as shared object to
// pass it from `data()` hook to
// `action()` hook`
this.conf.posts = posts;
resolve();
}
});
});
},
data() {
return this.conf.posts;
}
});
FlowRouter.route('/posts', {
name: 'posts',
waitOn() {
return import('/imports/client/posts.js');
}
});
FlowRouter.route('/posts', {
name: 'posts',
waitOn() {
return [
import('/imports/client/posts.js'),
import('/imports/client/sidebar.js'),
import('/imports/client/footer.js')
];
}
});
FlowRouter.route('/posts', {
name: 'posts',
waitOn() {
return [import('/imports/client/posts.js'), Meteor.subscribe('Posts')];
}
});
waitOnResources(params, qs)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
- Return: {Object}
{ images: ['url'], other: ['url'] }
.waitOnResources()
hook is triggered before .action()
hook, allowing to load necessary files, images, fonts before rendering a template.
FlowRouter.route('/images', {
name: 'images',
waitOnResources() {
return {
images:[
'/imgs/1.png',
'/imgs/2.png',
'/imgs/3.png'
]
};
},
});
Useful to preload background images and other globally used resources
FlowRouter.globals.push({
waitOnResources() {
return {
images: [
'/imgs/background/jpg',
'/imgs/icon-sprite.png',
'/img/logo.png'
]
};
}
});
This method will work only for cacheble resources, if URLs returns non-cacheble resources (dynamic resources) it will be useless.
Why Images and Other resources is separated? What the difference? - Images can be prefetched via Image()
constructor, all other resources will use XMLHttpRequest
to cache resources. Thats why important to make sure requested URLs returns cacheble response.
FlowRouter.route('/', {
name: 'index',
waitOnResources() {
return {
other:[
'/fonts/OpenSans-Regular.eot',
'/fonts/OpenSans-Regular.svg',
'/fonts/OpenSans-Regular.ttf',
'/fonts/OpenSans-Regular.woff',
'/fonts/OpenSans-Regular.woff2'
]
};
}
});
Useful to prefetch Fonts and other globally used resources
FlowRouter.globals.push({
waitOnResources() {
return {
other:[
'/fonts/OpenSans-Regular.eot',
'/fonts/OpenSans-Regular.svg',
'/fonts/OpenSans-Regular.ttf',
'/fonts/OpenSans-Regular.woff',
'/fonts/OpenSans-Regular.woff2'
]
};
}
});
whileWaiting(params, qs)
params
{Object} - Serialized route parameters,/route/:_id => { _id: 'str' }
qs
{Object} - Serialized query string,/route/?key=val => { key: 'val' }
- Return: {void}
.whileWaiting()
hook is triggered before .waitOn()
hook, allowing to display/render text or animation saying Loading...
.
FlowRouter.route('/post/:_id', {
name: 'post',
whileWaiting() {
this.render('loading');
},
waitOn(params) {
return Meteor.subscribe('post', params._id);
}
});
Note
Template helpers are available only if application has templating
and blaze
, or blaze-html-templates
packages installed
Returns the name of the current route
This adds support to get options from flow router
FlowRouter.route('name', {
name: 'routeName',
action() {
this.render('layoutTemplate', 'main');
},
coolOption: "coolOptionValue"
});
Template helper to check if the supplied path matches the currently active route's path.
Returns either a configurable String
, which defaults to 'active'
, or false
.
Template helper to check if the supplied route name matches the currently active route's name.
Returns either a configurable String
, which defaults to 'active'
, or false
.
Template helper to check if the supplied path doesn't match the currently active route's path.
Returns either a configurable String
, which defaults to 'disabled'
, or false
.
Template helper to check if the supplied route name doesn't match the currently active route's name.
Returns either a configurable String
, which defaults to 'disabled'
, or false
.
The following can be used by as arguments in isNotActivePath
, isNotActiveRoute
, isActivePath
and isActiveRoute
helpers.
- Data context, Optional.
String
orObject
withname
,path
orregex
name
{String} - Only available forisActiveRoute
andisNotActiveRoute
path
{String} - Only available forisActivePath
andisNotActivePath
regex
{String|RegExp}
Returns the value for a URL parameter
Used to build a path to your route. First parameter can be either the path definition or name you assigned to the route. After that you can pass the params needed to construct the path. Query parameters can be passed with the query
parameter. Hash is supported via hash
parameter.
Returns the value for a query parameter
Used to build an absolute URL to your route. First parameter can be either the path definition or name you assigned to the route. After that you can pass the params needed to construct the URL. Query parameters can be passed with the query
parameter. Hash is supported via hash
parameter.