How to find the previous page a user visited before landing on the current page.
Originally posted on www.grouparoo.com.
We have a form on our meet page (which, BTW, we'd love you to fill out because we like meeting new people). In addition to the data input from the user, we also wanted to capture how that user got to the page. That helps us determine which of our content is most effective in getting website visitors to take action.
document.referrer
AttemptMy gut was to start with document.referrer
. I've used it in the past with some success and it seemed like a simple solution.
The official spec says document.referrer
should do this:
Returns the URL of the Document from which the user navigated to this one, unless it was blocked or there was no such document, in which case it returns the empty string.
We have two problems with this approach:
<Link />
component, or the Next router, it will also be an empty string (i.e. no referrer).The latter issue was a deal-breaker because a good portion of the links within the site made use of Next's router, which provides a more performant experience for the user.
Although it feels a little hacky, we figured that we could do a little current-previous-current dance on every page load, using either localStorage
or sessionStorage
to store the values. It would work like this:
We decided on sessionStorage
over localStorage
because the session storage is cleared when the window or tab is closed. So if we have a previous page, then we can reasonably assume that's where the user came from. And we don't have to worry about clearing it when the page is unloaded.
To accomplish this, we used a React's useEffect
to adjust these values in our _app.tsx
file when the router's path changed. It looks like this:
// File: pages/_app.tsx
import { useRouter } from "next/router";
import { useEffect } from "react";
export default function GrouparooWWW(props) {
const router = useRouter();
useEffect(() => storePathValues, [router.asPath]);
function storePathValues() {
const storage = globalThis?.sessionStorage;
if (!storage) return;
// Set the previous path as the value of the current path.
const prevPath = storage.getItem("currentPath");
storage.setItem("prevPath", prevPath);
// Set the current path value by looking at the browser's location object.
storage.setItem("currentPath", globalThis.location.pathname);
}
// ...
}
Every time the router.asPath
value changes, storePathValues
fires, which adjusts our prevPath
and currentPath
values.
With this approach we are only capturing local traffic. But we don't have to worry about any special way of linking to the /meet
page. It just does its thing behind the scenes, regardless of whether the link to the page used Next's router or not.
If you're still super curious, here is the PR to our website that introduced this change.