I have a custom hook that will check whether you are logged in, and redirect you to the login page if you are not. Here is a pseudo implementation of my hook that assumes that you are not logged in:
import { useRouter } from 'next/router';
export default function useAuthentication() {
if (!AuthenticationStore.isLoggedIn()) {
const router = useRouter();
router.push('/login');
}
}
But when I use this hook, I get the following error:
Error: No router instance found. you should only use "next/router" inside the client side of your app. https://err.sh/vercel/next.js/no-router-instance
I checked the link in the error, but this is not really helpful because it just tells me to move the push statement to my render function.
I also tried this:
// My functional component
export default function SomeComponent() {
const router = useRouter();
useAuthentication(router);
return <>...</>
}
// My custom hook
export default function useAuthentication(router) {
if (!AuthenticationStore.isLoggedIn()) {
router.push('/login');
}
}
But this just results in the same error.
Is there any way to allow routing outside of React components in Next.js?
The error happens because router.push is getting called on the server during SSR on the page's first load. A possible workaround would be to extend your custom hook to call router.push inside a useEffect's callback, ensuring the action only happens on the client.
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function useAuthentication() {
const router = useRouter();
useEffect(() => {
if (!AuthenticationStore.isLoggedIn()) {
router.push('/login');
}
}, [router]);
}
Then use it in your component:
import useAuthentication from '../hooks/use-authentication' // Replace with your path to the hook
export default function SomeComponent() {
useAuthentication();
return <>...</>;
}
import Router from 'next/router'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With