├── README.md ├── createRouter.js ├── index.js └── package.js /README.md: -------------------------------------------------------------------------------- 1 | Meteor React Routing 2 | ==================== 3 | 4 | ## What ? 5 | A simple bridge between Meteor - FlowRouter - react-mounter. This package allows you 6 | to easily create your routes. For the rest / custom functionality check more on: 7 | 8 | https://github.com/kadirahq/flow-router 9 | 10 | For Basic Meteor Introduction, check Chapter 1 from: http://www.meteor-tuts.com 11 | 12 | ## Install 13 | ```bash 14 | meteor add cultofcoders:meteor-react-routing 15 | 16 | # make sure you have everything you need installed: 17 | meteor npm install --save react react-mounter react-dom 18 | ``` 19 | 20 | ```js 21 | // file: /imports/routing/router.js 22 | import { createRouter } from 'meteor/cultofcoders:meteor-react-routing'; 23 | import App from '/imports/ui/App.jsx'; // or the place where you have your main entry component 24 | 25 | export default createRouter(App); // App is the main entry component for your routes 26 | ``` 27 | 28 | ### App.jsx example: 29 | ```jsx 30 | // file: /imports/ui/App.jsx 31 | import React from 'react'; 32 | 33 | export default ({main, routeProps}) => { 34 | // main represents the component to render passed from the router 35 | // route props represent the properties that it receives from the router 36 | 37 | // where we do createElement, that's where your components will get rendered. 38 | return ( 39 |
40 | {React.createElement(main, routeProps)} 41 |
42 | ) 43 | } 44 | ``` 45 | 46 | ### API 47 | ```js 48 | import route from '/imports/routing/router.js'; 49 | 50 | route(path, Component, properties, flowRouterAdditionalOptions); 51 | ``` 52 | 53 | ### Basic usage 54 | 55 | ```js 56 | // file: /imports/routing/index.js 57 | 58 | import route from './router.js'; 59 | import Home from '/imports/ui/Home.jsx'; 60 | 61 | route('/', Home); 62 | ``` 63 | 64 | Meteor needs to be aware of our routes: 65 | 66 | ```js 67 | // file: /imports/startup/client/index.js 68 | 69 | import '/imports/routing'; 70 | ``` 71 | 72 | ### Parameters 73 | 74 | ```js 75 | route('/posts/:_id', PostView); 76 | 77 | // for the route '/posts/XXX' 78 | // in App.jsx routeProps will look like {_id: 'XXX'} 79 | // PostView will have access to _id by using this.props 80 | ``` 81 | 82 | ### Optional Parameters 83 | ```js 84 | route('/posts/:_id?', PostView); 85 | ``` 86 | 87 | ### Query Parameters 88 | ```js 89 | route('/posts/:_id', PostView); 90 | 91 | // accessing /posts/XXX?commentsPage=2 92 | // routeProps will look like: 93 | { _id: 'XXX', query: {commentsPage: 2} } 94 | ``` 95 | 96 | ### Extended Parameters 97 | ```js 98 | route('/admin/panel/categories', AdminPanel, { 99 | panel: 'categories' 100 | }); 101 | route('/admin/panel/something', AdminPanel, { 102 | panel: 'something' 103 | }); 104 | 105 | // accessing /admin/panel/categories 106 | // routeProps will look like: 107 | { panel: 'Something' } 108 | 109 | route('/admin/panel/view/:_id', AdminPanel, { 110 | panel: 'view' 111 | }); 112 | 113 | // accessing /admin/panel/view/XXX 114 | // routeProps will look like: (they will be embedded) 115 | { panel: 'Something', _id: XXX } 116 | ``` 117 | 118 | ### Dynamic Extended Parameters 119 | ```js 120 | route('/admin/panel/view/:_id', AdminPanel, (params, queryParams) => { 121 | return {something: true}; 122 | }); 123 | 124 | 125 | // accessing /admin/panel/view/XXX 126 | // routeProps will look like: 127 | { something: true } 128 | 129 | // if you want to use the params and queryParams passed to routeProps you have to do it manually 130 | // something like: 131 | route('/admin/panel/view/:_id', AdminPanel, (params, queryParams) => { 132 | return _.extend({}, params, {query: queryParams}, {something: true}); 133 | }); 134 | ``` 135 | 136 | ### Generating Routes 137 | ```js 138 | // route('/posts/:_id', PostView); 139 | import router from '/imports/routing/router.js'; 140 | 141 | router.path('/posts/:_id', {_id: 'XXX'}) // returns /posts/XXX 142 | 143 | // if you want query parameters: 144 | router.path('/posts/:_id', {_id: 'XXX'}, {page: 2}) // returns /posts/XXX?page=2 145 | ``` 146 | 147 | ### Named Routes 148 | ```js 149 | import route from '/imports/routing/router.js'; 150 | route('/posts/:_id', PostView, {}, { 151 | name: 'post_view' 152 | }) 153 | 154 | // generating the route with the name: 155 | route.path('post_view', {_id: 'XXX'}) // returns /posts/XXX 156 | ``` 157 | 158 | ### Travel to a different route. 159 | 160 | An action happens, someone submitted a form, you want to take him to the list or some other place: 161 | 162 | ``` 163 | import route from '/imports/routing/router.js'; 164 | 165 | route.go('/posts/:_id', {_id: 'XXX'}, {page: 2}) // pathDef, params, queryParams 166 | 167 | // or for a named route: 168 | route.go('post_view', {_id: 'XXX'}, {page: 2}) // pathDef, params, queryParams 169 | ``` 170 | 171 | ### Getting the current route 172 | ```js 173 | import route from '/imports/routing/router.js'; 174 | 175 | console.log(route.current()) 176 | // prints following object 177 | { 178 | path: "/apps/this-is-my-app?show=yes&color=red", 179 | params: {appId: "this-is-my-app"}, 180 | queryParams: {show: "yes", color: "red"} 181 | route: {pathDef: "/apps/:appId", name: "name-of-the-route"} 182 | } 183 | ``` 184 | 185 | ### Advanced usage and hooks 186 | 187 | Check out flow-router, the 4th parameter from route() lets you do all the other options that you want like: 188 | - triggersEnter 189 | - triggersExit 190 | - name 191 | 192 | ### User Aware Layouts 193 | 194 | First make sure you give this a read: 195 | https://guide.meteor.com/react.html#using-createContainer 196 | 197 | ```bash 198 | // terminal 199 | meteor add react-meteor-data 200 | ``` 201 | 202 | ```js 203 | // file: /imports/api/App.jsx 204 | import React from 'react'; 205 | import { createContainer } from 'meteor/react-meteor-data'; 206 | import NavBar from '/imports/ui/NavBar.jsx'; 207 | 208 | const App = ({main, routeProps, user}) => { 209 | return ( 210 |
211 | {user ? : null} 212 | {React.createElement(main, routeProps)} 213 |
214 | ) 215 | }) 216 | 217 | export default createContainer((props) => { 218 | const user = Meteor.user(); 219 | 220 | return _.extend(props, {user}); 221 | }, App); 222 | ``` 223 | 224 | ### Further reading: 225 | 226 | Read more on: https://github.com/kadirahq/flow-router#routes-definition -------------------------------------------------------------------------------- /createRouter.js: -------------------------------------------------------------------------------- 1 | import { mount } from 'react-mounter'; 2 | import { _ } from 'meteor/underscore'; 3 | 4 | export default function (App) { 5 | let handler = (path, component, propsFn, options = {}) => { 6 | _.extend(options, { 7 | action(params, queryParams) { 8 | let componentProps = {}; 9 | if (_.isFunction(propsFn)) { 10 | componentProps = propsFn.call(propsFn, params, queryParams); 11 | } else if (_.isObject(propsFn)) { 12 | componentProps = _.extend(params, propsFn); 13 | } else { 14 | componentProps = params; 15 | } 16 | 17 | if (queryParams) { 18 | _.extend(componentProps, { 19 | query: queryParams 20 | }) 21 | } 22 | 23 | mount(App, {main: component, routeProps: componentProps}); 24 | } 25 | }); 26 | 27 | FlowRouter.route(path, options); 28 | }; 29 | 30 | handler.add = handler.bind(FlowRouter); 31 | handler.path = FlowRouter.path.bind(FlowRouter); 32 | handler.current = FlowRouter.current.bind(FlowRouter); 33 | handler.go = FlowRouter.go.bind(FlowRouter); 34 | 35 | return handler; 36 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import createRouter from './createRouter'; 2 | 3 | export { createRouter } -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'cultofcoders:meteor-react-routing', 3 | version: '1.0.3', 4 | // Brief, one-line summary of the package. 5 | summary: 'Very easy way to build routes for your Meteor + React application', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.4.1.3'); 15 | api.use('ecmascript'); 16 | api.use('underscore'); 17 | 18 | api.use('kadira:flow-router@2.12.1'); 19 | api.imply('kadira:flow-router@2.12.1'); 20 | 21 | api.mainModule('index.js', 'client'); 22 | }); 23 | 24 | // No testing yet, feel free to contribute. 25 | // Package.onTest(function(api) { 26 | // api.use('ecmascript'); 27 | // api.use('tinytest'); 28 | // }); 29 | --------------------------------------------------------------------------------