Meteor React Routing
What ?
A simple bridge between Meteor - FlowRouter - react-mounter. This package allows you to easily create your routes. For the rest / custom functionality check more on:
https://github.com/kadirahq/flow-router
For Basic Meteor Introduction, check Chapter 1 from: http://www.meteor-tuts.com
Install
meteor add cultofcoders:meteor-react-routing # make sure you have everything you need installed: meteor npm install --save react react-mounter react-dom
1// file: /imports/routing/router.js 2import { createRouter } from 'meteor/cultofcoders:meteor-react-routing'; 3import App from '/imports/ui/App.jsx'; // or the place where you have your main entry component 4 5export default createRouter(App); // App is the main entry component for your routes
App.jsx example:
1// file: /imports/ui/App.jsx 2import React from 'react'; 3 4export default ({main, routeProps}) => { 5 // main represents the component to render passed from the router 6 // route props represent the properties that it receives from the router 7 8 // where we do createElement, that's where your components will get rendered. 9 return ( 10 <div id="app"> 11 {React.createElement(main, routeProps)} 12 </div> 13 ) 14}
API
1import route from '/imports/routing/router.js'; 2 3route(path, Component, properties, flowRouterAdditionalOptions);
Basic usage
1// file: /imports/routing/index.js 2 3import route from './router.js'; 4import Home from '/imports/ui/Home.jsx'; 5 6route('/', Home);
Meteor needs to be aware of our routes:
1// file: /imports/startup/client/index.js 2 3import '/imports/routing';
Parameters
1route('/posts/:_id', PostView); 2 3// for the route '/posts/XXX' 4// in App.jsx routeProps will look like {_id: 'XXX'} 5// PostView will have access to _id by using this.props
Optional Parameters
1route('/posts/:_id?', PostView);
Query Parameters
1route('/posts/:_id', PostView); 2 3// accessing /posts/XXX?commentsPage=2 4// routeProps will look like: 5{ _id: 'XXX', query: {commentsPage: 2} }
Extended Parameters
1route('/admin/panel/categories', AdminPanel, { 2 panel: 'categories' 3}); 4route('/admin/panel/something', AdminPanel, { 5 panel: 'something' 6}); 7 8// accessing /admin/panel/categories 9// routeProps will look like: 10{ panel: 'Something' } 11 12route('/admin/panel/view/:_id', AdminPanel, { 13 panel: 'view' 14}); 15 16// accessing /admin/panel/view/XXX 17// routeProps will look like: (they will be embedded) 18{ panel: 'Something', _id: XXX }
Dynamic Extended Parameters
1route('/admin/panel/view/:_id', AdminPanel, (params, queryParams) => { 2 return {something: true}; 3}); 4 5 6// accessing /admin/panel/view/XXX 7// routeProps will look like: 8{ something: true } 9 10// if you want to use the params and queryParams passed to routeProps you have to do it manually 11// something like: 12route('/admin/panel/view/:_id', AdminPanel, (params, queryParams) => { 13 return _.extend({}, params, {query: queryParams}, {something: true}); 14});
Generating Routes
1// route('/posts/:_id', PostView); 2import router from '/imports/routing/router.js'; 3 4router.path('/posts/:_id', {_id: 'XXX'}) // returns /posts/XXX 5 6// if you want query parameters: 7router.path('/posts/:_id', {_id: 'XXX'}, {page: 2}) // returns /posts/XXX?page=2
Named Routes
1import route from '/imports/routing/router.js'; 2route('/posts/:_id', PostView, {}, { 3 name: 'post_view' 4}) 5 6// generating the route with the name: 7route.path('post_view', {_id: 'XXX'}) // returns /posts/XXX
Travel to a different route.
An action happens, someone submitted a form, you want to take him to the list or some other place:
import route from '/imports/routing/router.js'; route.go('/posts/:_id', {_id: 'XXX'}, {page: 2}) // pathDef, params, queryParams // or for a named route: route.go('post_view', {_id: 'XXX'}, {page: 2}) // pathDef, params, queryParams
Getting the current route
1import route from '/imports/routing/router.js'; 2 3console.log(route.current()) 4// prints following object 5{ 6 path: "/apps/this-is-my-app?show=yes&color=red", 7 params: {appId: "this-is-my-app"}, 8 queryParams: {show: "yes", color: "red"} 9 route: {pathDef: "/apps/:appId", name: "name-of-the-route"} 10}
Advanced usage and hooks
Check out flow-router, the 4th parameter from route() lets you do all the other options that you want like:
- triggersEnter
- triggersExit
- name
User Aware Layouts
First make sure you give this a read: https://guide.meteor.com/react.html#using-createContainer
// terminal meteor add react-meteor-data
1// file: /imports/api/App.jsx 2import React from 'react'; 3import { createContainer } from 'meteor/react-meteor-data'; 4import NavBar from '/imports/ui/NavBar.jsx'; 5 6const App = ({main, routeProps, user}) => { 7 return ( 8 <div id="app"> 9 {user ? <NavBar user={user} /> : null} 10 {React.createElement(main, routeProps)} 11 </div> 12 ) 13}) 14 15export default createContainer((props) => { 16 const user = Meteor.user(); 17 18 return _.extend(props, {user}); 19}, App);
Further reading:
Read more on: https://github.com/kadirahq/flow-router#routes-definition