├── 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 |
--------------------------------------------------------------------------------