How to access previous route in Next.js 14 using App Router?

clock icon

asked 2 months ago Asked

message

5 Answers

eye

88 Views

Existing threads are mostly relevant to the Pages router.

I know that with react router I'm able to do this:

const history = useHistory();
const { pathname } = useLocation();

history.push('/', { from: pathname }) 

And then access the previous path like so:

const Home = (props) => {
   console.log(props.location.state.from);
}

But how do I achieve this in NextJS 14 using the App Router?

I tried accessing asPath prop bbut apparently it was removed:

 

const usePreviousRoute = () => {
  const { asPath } = useRouter();

  const ref = useRef<string | null>(null);

  useEffect(() => {
    ref.current = asPath;
  }, [asPath]);

  return ref.current;
};

5 Answers

Define the context:

'use client';

import { useContext, useEffect, useState, createContext } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';

export const useNavigationContext = () => useContext(NavigationContext);

export const NavigationProvider = ({ children }: { children: React.ReactNode }) => {
  const navigation = useNavigation();

  return <NavigationContext.Provider value={navigation}>{children}</NavigationContext.Provider>;
};

const useNavigation = () => {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const [currentRoute, setCurrentRoute] = useState<string | null>(null);
  const [previousRoute, setPreviousRoute] = useState<string | null>(null);

  useEffect(() => {
    const url = `${pathname}?${searchParams}`;
    setPreviousRoute(currentRoute);
    setCurrentRoute(url);
  }, [pathname, searchParams]);

  return { previousRoute };
};

const NavigationContext = createContext<ReturnType<typeof useNavigation>>({
  previousRoute: null,
});

Use Provider in RootLayout:

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <NavigationProvider>
         {children}
        </NavigationProvider>
      </body>
    </html>
  );
}

Consume in Client Component:

'use client';

import Link from 'next/link';

import { useNavigationContext } from '@/contexts';

const BackButton = () => {
  const { previousRoute } = useNavigationContext();

  return <Link href={previousRoute ?? '/'}>Go back</Link>;
};

export default BackButton;

You can get this with the referrer header, provided you have set up your headers to allow this.

headers: {
  ...other headers...
  { key: 'Referrer-Policy', value: 'origin-when-cross-origin' },
}

In your server component:

import { headers } from 'next/headers'

const BackBtn = () => {
  const headersList = headers()
  const referer = headersList.get('referer')
}

Write your answer here

Top Questions