Create smooth return navigation with Remix. This library retains all existing state within a URL, promotes the use of native web practices for navigation, and makes return navigation easy to implement for both clients with and without Javascript enabled.
npm i --save @briandlee/remix-return-navigation
The live demo is available at https://remix-return-navigation.brian-dlee.dev/.
The code for the demo is in the demo directory.
Installing the context allows the application to encapsulate the server provided
referrer as we as listening for client-side navigations. The context must be installed so
that the returnLocation
will be computed and available to ForwardLink
components.
import type { LoaderFunction } from '@remix-run/node';
import { json } from '@remix-run/node';
import {
getReturnNavigationState,
ReturnNavigationContextProvider,
} from '@briandlee/remix-return-navigation';
export const loader: LoaderFunction = async ({ request }) => {
const state = getReturnNavigationState(request);
return json({ referrer: state.referrer, requestUrl: state.requestUrl });
};
export default function App() {
const { referrer, requestUrl } = useLoaderData();
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<ReturnNavigationContextProvider referrer={referrer} requestUrl={requestUrl}>
<Outlet />
</ReturnNavigationContextProvider>
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
Add a ForwardLink
to automatically add a return location to a link.
Note:
ForwardLink
wrapsLink
from@remix-run/react
. It only adds the current location as a search param to enable return navigation.
import { ForwardLink } from '@briandlee/remix-return-navigation';
export default function SourcePage() {
return (
<div>
<h1>Hello, {user.displayName}</h1>
<ForwardLink to={'target'}>Go</ForwardLink>
</div>
);
}
Add a BackwardLink
to add a link to return the user to the previous location.
Note:
BackwardLink
also wrapsLink
from@remix-run/react
, but it does not acceptto
since it generates it from the current return location.
import type { LoaderFunction } from '@remix-run/node';
import { json } from '@remix-run/node';
import { BackwardLink } from '@briandlee/remix-return-navigation';
export default function TargetPage() {
return (
<div>
<h1>Hello, {user.displayName}</h1>
<BackwardLink fallback="/profile" fallbackContent={"Go to Profile"}>
Return
</BackwardLink>
</div>
);
}
import type {LoaderFunction} from '@remix-run/node';
import {json} from '@remix-run/node';
import {BackwardLink, BackwardLinkFC} from '@briandlee/remix-return-navigation';
export default function TargetPage() {
return (
<div>
<h1>Hello, {user.displayName}</h1>
<BackwardLink render={LinkContent} />
</div>
);
}
const LinkContent: BackwardLinkFC = ({ returnLocation }) => {
if (returnLocation) {
return (
<><Icon name={'back'} /> Go back to {returnLocation.pathname}</>
)
return <><Icon name={'home'} /> Go home</>
}
}
Works around a known issue: remix-run/remix#3510
Created by me.