Reset the Navigation Stack after logout in NextJS(App Router)

98 Views Asked by At

I am creating a logout functionality in nextjs by clicking the logout button on user profile. The first page is the landing page where (as usual ) the token is checked and the user is replaced either to home of login. Now when the user is logged out in userprofile i send it to Landing page ('/') the user is send to login page and on clicking back it jumps to home page which should never happen. My question is how to reset the stack navigator on logout or i should move to another approach. Open for good code changes

Happy coding

USERPROFILE

import React, { useEffect } from 'react'

import AppHeader from '@/components/AppHeader'
import ReadOnlyText from '@/components/ReadOnlyText'
import { colors } from '@/styles/colors'
import { EMAIL, MY_PROFILE, NAME } from '@/utils/constants/textConstants'
import { Grid } from '@mui/material'
import { useAppDispatch, useAppSelector } from '@/redux/store'
import CustomButton from '@/components/CustomButton'
import { logoutAction } from '@/redux/slices/authSlice'
import Cookies from 'js-cookie'
import { useRouter } from 'next/navigation'


const UserProfile = () => {

  const dispatch = useAppDispatch()
  const router = useRouter()

  const user = useAppSelector(state => state.auth.user)
  const logoutuResp = useAppSelector(state => state.auth.logoutResp)

  const onClickLogout = () => {
    // dispatch(logoutAction())
    Cookies.remove('token')
    router.replace('/',)
  }



  return (
    <Grid container sx={{ backgroundColor: colors.white }}    >
      <AppHeader title={MY_PROFILE} />
      <Grid item xs={12} paddingInline={2}  >
        <Grid>
          <ReadOnlyText label={EMAIL} value={user?.email ? user.email : '-'} />
          <ReadOnlyText label={NAME} value={user?.name ? user.name : '-'} />
        </Grid>
        <Grid mt={4} >
          <CustomButton label='Logout' onClick={onClickLogout} sx={{ backgroundColor: colors.error }} />
        </Grid>
      </Grid>
    </Grid >
  )
}

export default UserProfile

LANDING PAGE

"use client"

import { useEffect } from "react"
import Cookies from 'js-cookie'
import { useRouter, useSearchParams, useParams } from "next/navigation";

import { HOME_ROUTE, LOGIN_ROUTE } from "@/utils/constants/routeConstants"

import ScreenLoader from "@/components/ScreenLoader";
import { useDispatch } from "react-redux";
import { DeviceConfigType } from "@/types";
import { setDeviceConfigAction, showToastAction } from "@/redux/slices/configSlice";
import { useAppSelector } from "@/redux/store";

const LandingPage = () => {

    //
    const deviceConfig = useAppSelector(state => state.config.deviceConfig)
    //
    const router = useRouter()
    const dispatch = useDispatch()
    const searchParams = useSearchParams()
    let token = Cookies.get('token')
    let configKeys: string[] = ['fcmToken', 'deviceInfo', 'appVersion', 'ipAddress', 'latitude', 'longitude']

    useEffect(() => {
        if (deviceConfig === null && searchParams.size > 0) {
            const missingConfigs = configKeys.filter(item => !searchParams.has(item));
            if (missingConfigs.length === 0) {
                const userConfig = Object.fromEntries(searchParams.entries());
                dispatch(setDeviceConfigAction(userConfig));
            } else {
                handleConfigFetchError()
            }
        } else if (deviceConfig === null) {
            handleConfigFetchError()
        }
    }, [searchParams, deviceConfig])

    useEffect(() => {
        if (deviceConfig !== null) {
            //means config fetched successfully
            handleConfigFetchSuccess()
        }
    }, [token, deviceConfig])


    const handleConfigFetchError = () => {
        dispatch(showToastAction({
            message: 'Config fetch error',
            slug: 'error'
        }));
    };

    const handleConfigFetchSuccess = () => {
        if (token) {
            router.replace(HOME_ROUTE);
        } else {
            router.replace(LOGIN_ROUTE);
        }
    };

    return (
        <div>
            <ScreenLoader isLoading={true} />
        </div>
    )
}

export default LandingPage
1

There are 1 best solutions below

0
Youssouf Oumar On

You cannot clear the browser navigation stack. It's not a Next.js problem, but JavaScript itself cannot. As you can read on MDN says:

There is no way to clear the session history or to disable the back/forward navigation from unprivileged code. The closest available solution is the location.replace(url) method, which replaces the current item of the session history with the provided URL.

And location.replace(url) is kinda like router.replace(url). I would simply have a check for the cookie in /home as well, and redirect to the login page if there isn't one. This check is relevant as someone can directly come to /home anyway, with a URL, for example.