1

Let's say there are three pages - A, B, and C.

I can navigate from A to C and from B to C as well, but the view of C depends on the page from which we are navigating.

I would like to know how we can identify in Next.js from which page we are routing to page C.

Page C has a dynamic route

TIA

  • You might want to rethink the design here. Why not have page C accept a URL query parameter which varies its behavior how you want. Then, not only can you simply generate two different links to C from A and B, but you have a stable URL which you can link to. – Josh Bothun May 11 '22 at 09:50
  • https://stackoverflow.com/a/63235122/5833816 – Lazar Nikolic May 11 '22 at 09:51
  • @minism The page C is actually a dynamic route. – Mohit Chauhan May 11 '22 at 09:53
  • @MohitChauhan Even with a dynamic route, you can append a query parameter. – Josh Bothun May 11 '22 at 09:55
  • @minism yes, but is there any other way doing it, without using query paramter – Mohit Chauhan May 11 '22 at 09:56
  • 1
    Probably, but what's the reasoning? A query parameter is the standard practice in web design for dynamic page behavior like you've described. Consider that without this, refreshing the page could lose your state. – Josh Bothun May 11 '22 at 09:59

3 Answers3

0

You could pass the previous location as query data:

<Link
  href={{
    pathname: "/some-page",
    query: "current location", // the data
  }}
>
  <a>Some Text</a>
</Link>

Then you can retrieve the query data:

const router = useRouter();
const data = router.query;

If you don't like the idea of passing the previous location as a query, you could save the current location in a global state, like Redux on a page mount, after reading the previous value, which represents the previous location pathname.

Ahmed Sbai
  • 10,695
  • 9
  • 19
  • 38
Cesare Polonara
  • 3,473
  • 1
  • 9
  • 19
0

You can get advantage of getServerSideProps since the function is called on every request.

export async function getServerSideProps(context) {
  const from = context.req.headers.referer ;  
  //...

  return {
    props: {
      from,
      //...
    },
  };
}

The property refer represents the url of the page that called your current page.

Note: the property refer will no exist in context.req.headers if the user enters the URL manually props.from will be passed as undefined to the page.


Now you have the property from available in the props object passed to your page you can know from wich url the current page is called so you can decide what to do based on that.

Ahmed Sbai
  • 10,695
  • 9
  • 19
  • 38
0

I created a history provider with React context. I use it to hide elements on a page when the user comes from another specific page.

  1. Create the Provider and the context, and a hook to facilitate the usage:
// src/common/providers/history-provider.tsx
import { createContext, FC, ReactNode, useContext, useEffect, useState } from 'react';
import { useRouter } from 'next/router';

const HistoryContext = createContext<string[]>([]);

interface Props {
  children: ReactNode;
}

export const HistoryProvider: FC<Props> = ({ children }) => {
  const { asPath } = useRouter();
  const [history, setHistory] = useState<string[]>([]);

  useEffect(() => {
    setHistory((previous) => [...previous, asPath]);
  }, [asPath]);

  return <HistoryContext.Provider value={history}>{children}</HistoryContext.Provider>;
};

export function useHistory(): string[] {
  return useContext(HistoryContext);
}

  1. Wrap your application with the provider:
// src/pages/_app.tsx
import type { AppProps } from 'next/app';
import { RootLayout } from '@/common/layouts/root';
import 'react-toastify/dist/ReactToastify.css';
import { HistoryProvider } from 'common/providers/history-provider';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <RootLayout>
      <HistoryProvider>
        <Component {...pageProps} />
      </HistoryProvider>
    </RootLayout>
  );
}
  1. Use the hook useHistory to get the path history in your component:
// src/features/x/components/component-x.tsx
export const ComponentX: FC = () => {
  const history = useHistory();

  const comingFromAdding = (): boolean => {
    if (history.length < 2) return false;
    return !history.at(-2)?.includes('add');
  };

  if(comingFromAdding()) // do something...
  
  // ...
}
Oliver Sosa
  • 754
  • 9
  • 16