ivo
August 6, 2018, 5:08pm
1
Hi everyone.
I am starting an app with SSR and I followed this great article :
Everything worked fine and easy until I reached accounts management. I’d like to know more about handling users Method from accounts-base which apparently are not rechable on server side.
I used to have client rendered apps and it was easy to manage but now I am struggling a lot. For example I like to give an isAdmin boolean to my users and publish it as userData. This boolean is compulsory to reach my /admin panel, and now the only way I found to make this work was this :
export class Admin extends React.Component {
render () {
if (Meteor.isClient){
if(Meteor.user()) {
if(Meteor.user().isAdmin){
return (
<div className="admin">
Admin
</div>
)
} else {
return (<Redirect to="/" />)
}
} else if(this.props.loggingIn) {
return null;
} else {
return (<Redirect to="/" />)
}
} else {
return (<Redirect to="/" />)
}
}
}
export default withTracker(() => {
if (Meteor.isClient){
const loggingIn = Meteor.loggingIn()
return { loggingIn }
}
return {}
})(Admin)
Seems very complicated to me, anyone has any idea how I could manage this better ?
minhna
August 7, 2018, 5:15am
2
You can turn off ssr for admin pages.
ivo
August 7, 2018, 5:29am
3
Any leads on where to find the doc about this, still very new to SSR. But thanks for the tip.
minhna
August 7, 2018, 5:39am
4
Here is an example:
onPageLoad(async (sink) => {
// try to disable server render for some pages
const { url } = sink.request;
const adminRegex = new RegExp('^/admin/');
if (adminRegex.test(url.path)) {
return;
}
// do the rest server render here
}
1 Like
ivo
August 7, 2018, 5:41am
5
Ok thanks, will try that, though not yet sure or where to put it in relation to the StaticRouter on the server side.
Right now I have this:
onPageLoad((sink) => {
const context = {};
const store = createStore(mainReducer, { selectedIndex : 0}, applyMiddleware(thunk))
const App = props => (
<Provider store={store}>
<StaticRouter location={props.location} context={context}>
{routes}
</StaticRouter>
</Provider>
);
App.propTypes = {
location: object.isRequired,
};
const preloadedState = store.getState();
sink.renderIntoElementById('app', renderToString(<App location={sink.request.url} />));
sink.appendToBody(`
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
</script>
`);
});
Shall I return before I even reach the Router ?
minhna
August 7, 2018, 5:42am
6
Yes. Try to return on very top of function.
ivo
August 7, 2018, 6:37am
7
Thanks a lot, seems to work, code now is like that :
render () {
if(!this.props.ready){
return null
}
if (!this.props.user || !this.props.user.isAdmin){
return (<Redirect to="/" />)
}
return (
<div className="admin">
<h1>Admin</h1>
<AddCategory />
</div>
)
}
}
export default withTracker(() => {
let subUSerData = Meteor.subscribe('userData');
const loggingIn = Meteor.loggingIn();
const user = Meteor.user()
return { loggingIn, ready: subUSerData.ready(), user }
})(Admin)
and added following lines right after onPageLoad on server side:
if(['/login','/signup', '/admin'].indexOf(sink.request.url.pathname) > -1){
return
}