Skip to content

Instantly share code, notes, and snippets.

@cstrat
Last active December 27, 2018 09:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cstrat/443aec538c12d5e1957e51848b926c50 to your computer and use it in GitHub Desktop.
Save cstrat/443aec538c12d5e1957e51848b926c50 to your computer and use it in GitHub Desktop.
Meteor + React Router: Reactive Protected Routes
import React from "react";
import { render } from "react-dom";
import { Meteor } from "meteor/meteor";
import { withTracker } from "meteor/react-meteor-data";
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
// Constant Components
import Header from "./ui/components/Header";
import Footer from "./ui/components/Footer";
// Page & Route Components
import Home from "./ui/pages/Home";
import Admin from "./ui/pages/Admin";
import Account from "./ui/pages/Account";
// Load the React App
Meteor.startup(() => {
render(
<AppContainer />,
document.getElementById("root")
);
});
// App Container & Routes
App = () => {
const { loggingIn } = this.props;
return(
<Router>
<Header />
<Switch>
<Route exact path="/" component={Home} />
<ProtectedRoute loggingIn={loggingIn} exact path="/account" component={Account} />
<AdminRoute loggingIn={loggingIn} exact path="/admin" component={Admin} />
<Route component={NotFound} />
</Switch>
<Footer />
</Router>
);
}
// Reactive Container
const AppContainer = withTracker(() => ({
loggingIn: Meteor.loggingIn()
}))(App);
// Must be logged in for this route... Briefly shows '...' while loading account data rather than redirecting...
const ProtectedRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props => {
const isLoggedIn = Meteor.userId() !== null;
return rest.loggingIn ? <span>...</span> : isLoggedIn ? <Component {...props} /> : <Redirect to={{ pathname: "/" }} />;
}}
/>
);
// Must be logged in as an admin for this route... Briefly shows '...' while loading account data rather than redirecting...
const AdminRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props => {
const isAdmin = Meteor.user() ? Meteor.user().admin : false;
return rest.loggingIn ? <span>...</span> : isAdmin ? <Component {...props} /> : <Redirect to={{ pathname: "/" }} />;
}}
/>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment