Essentially I created a HOC for two pages in my Next.js app (i.e. profile
and dashboard
) two prevent users from accessing them if they're not authorized.
Example: pages/profile.js
import withAuth from "../components/AuthCheck/index";
function Profile() {
return (
<>
<h1>Profile</h1>
</>
)
}
export default withAuth(Profile);
My Auth component/HOC:
import { useRouter } from 'next/router'
import { useUser } from '../../lib/hooks'
import { PageLoader } from '../Loader/index'
const withAuth = Component => {
const Auth = (props) => {
const { isError } = useUser(); //My hook which is calling /api/user see if there is a user
const router = useRouter()
if (isError === 'Unauthorized') {
if (typeof window !== 'undefined' && router.pathname === '/profile' || router.pathname === 'dashboard') router.push('/login')
return <PageLoader />
}
return (
<Component {...props} />
);
};
if (Component.getInitialProps) {
Auth.getInitialProps = Component.getInitialProps;
}
return Auth;
};
export default withAuth;
Now what is happening is if you happen to enter /profile
or /dashboard
in the browser URL bar, before the redirect you'll see the page for a second i.e. flash.
Any idea why that is happening?
I'd consider making use of getServerSideProps on pages that need to be authed, have a look at getServerSideProps . It'll run server side on a page per request.
Alternatively, it might make sense (depending on your project setup - especially if you have access to auth state in _app.tsx_
) to render the auth component in your _app
. More specifically, you could add a protected:true
prop to the pages that are behind auth wall (using static props). Then in app you can check if a particular page has protected===true and redirect to auth component if the user isn't authed, for example:
{pageProps.protected && !user ? (
<LoginComponent />
) : (
<Component {...pageProps} />
)}