Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use NextRouter outside of React component

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?

like image 494
Titulum Avatar asked Nov 28 '25 17:11

Titulum


2 Answers

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 <>...</>;
}
like image 141
juliomalves Avatar answered Nov 30 '25 06:11

juliomalves


import Router from 'next/router'

like image 29
HalfWebDev Avatar answered Nov 30 '25 07:11

HalfWebDev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!