I wonder if there is a way to inject that into the server’s execution context, so that APIs like Meteor.user() will “just work”.
If we do need to go the route of propagating the user state through the app, a Provider sounds like a good way to go. I actually do something similar already in my apps, and it would be easy to adapt it to your solution:
/* global Meteor */
import { createContext, useContext } from 'react'
import { useTracker } from 'meteor/react-meteor-data'
import { isSuperAdmin } from '/imports/utils/roles'
// This can be used directly, but is also used by the Context provider
export const useAccountDirect = () => useTracker(() => {
const user = Meteor.isServer ? null : Meteor.user()
const userId = Meteor.isServer ? null : Meteor.userId()
return {
user,
userId,
isLoggedIn: !!userId,
isSuperAdmin: isSuperAdmin(userId)
}
}, [])
const AccountContext = createContext('account')
export const AccountProvider = (props) => (
<AccountContext.Provider value={useAccountDirect()}>
{props.children}
</AccountContext.Provider>
)
export const AccountConsumer = AccountContext.Consumer
export const useAccount = () => useContext(AccountContext)
// Replaces the old HOC based on `withTracker` for class based components
export const withUser = (Component) => (props) => {
const account = useAccountContext()
return <Component {...props} {...account} />
}
Thanks for the suggestion @captainn, I agree I think Meteor.user() should just work during SSR to keep the Meteor magic.
I’ve updated the package to patch Meteor.user() on the server during SSR. I plan to do the same for the client method to make it just work (including roles).
I’ll add an attribute to the user (ssrUser) to differentiate the user from SSR and that from DDP.