0

I have a next JS application whose logged in pages are protected by a requireAuth component:

import useAuth from '../../hooks/useAuth';
import { useRouter } from 'next/router';
import { useEffect } from 'react';

const RequireAuth = ({ children }) => {
  const router = useRouter();
  const { auth } = useAuth();
  // from location is saved in router query
  // this is used to redirect to the same page after login
  // const from = router.query.from || '/'; in login.jsx
  useEffect(() => {
    if (!auth?.user) {
      router.push({
        pathname: '/seller/auth/login',
        query: { from: router.pathname },
      });
    }
  }, [auth?.user]);

  return <div>{children}</div>;
};

export default RequireAuth;

The require auth retains the page the user was on as query parameter so that the user can be sent to respective page after login.

However, if the user logs out from a page referred by a dynamic parameter:

E.g. http://localhost:3000/seller/panel/products/1

Where 1 refers to the [productId].js page

Then the URL string on login page comes to be the below:

http://localhost:3000/seller/auth/login?from=%2Fseller%2Fpanel%2Fproducts%2F%5BproductId%5D

here, after login user is not sent to http://localhost:3000/seller/panel/products/1 and thrown an error.

Please help to resolve this.

Update:

What error is thrown:

Unhandled Runtime Error Error: The provided href (/seller/panel/products/[productId]) value is missing query values (productId) to be interpolated properly. Read more: https://nextjs.org/docs/messages/href-interpolation-failed

How do you redirect after login:

In My login component:

const router = useRouter();
  const from = router.query.from || '/seller/panel';

  const handleLogin = async (e) => {
    e.preventDefault();
    // regex to test valid email
    const emailRegex =
      /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    const phoneRegex = /^[0-9]{10}$/;
    if (
      !emailRegex.test(values.phoneEmail) &&
      !phoneRegex.test(values.phoneEmail)
    ) {
      setResSuccess(false);
      setResMessage('Please enter a valid email or phone number');
      return;
    }
    setResMessage('');

    setLoading(true);
    const response = await passwordLogin(values);
    // console.log(response);
    setLoading(false);

    const { success, message, user, roles, stores, accessToken } =
      response.data;
    setResSuccess(success);
    setResMessage(message);
    if (success) {
      setAuth({ user, roles, stores, accessToken });
      setValues({
        phoneEmail: '',
        password: '',
        otp: '',
      });
      router.push(from);
    }
  };
ajhavery
  • 264
  • 7
  • 16

1 Answers1

1

Figured this out:

router.pathName gives:

pathname: /products/[productId]

router.asPath gives:

pathname: /products/1

ajhavery
  • 264
  • 7
  • 16