usePathname in useEffect not triggering
Unanswered
Scottish Fold posted this in #help-forum
Scottish FoldOP
Hello. Since the router.events was deprecated in next14+ the official documentation says to use the usePathname in the useEffect trigger. https://nextjs.org/docs/app/api-reference/functions/use-pathname#parameters
I'm trying to use it here (nextjs 14.2.8 app router):
however this is only triggered on inital page load, whenever i navigate away from the page, it doesn't do anything. I would guess that the trigger is too slow? Has anyone ran into it or how have you solved the issue where someone navigates away from some X path and you want to do some actions (like save some data on the page or something when the user leaves). I can use onbeforeunload for refresh and closing the page but not navigating somewhere else within the page.
I'm trying to use it here (nextjs 14.2.8 app router):
import { usePathname } from "next/navigation";
const pathname = usePathname();
useEffect(() => {
console.log("pathname change triggered")
}, [pathname]);however this is only triggered on inital page load, whenever i navigate away from the page, it doesn't do anything. I would guess that the trigger is too slow? Has anyone ran into it or how have you solved the issue where someone navigates away from some X path and you want to do some actions (like save some data on the page or something when the user leaves). I can use onbeforeunload for refresh and closing the page but not navigating somewhere else within the page.
16 Replies
Commenting to follow. I am curious.
Scottish FoldOP
okay, looks like i got it working. I used it wrong. usePathname actually doesn't trigger useEffect but useSearchParams does. It's not very intuitive because logically you'd think that path change would trigger pathname change.
So, here's how i handled the trigger when user navigates to some other part of your page and you want to do some custom logic things when user leaves (in my case i wanted to store data in memory until user has finished and then save everything all at once rather than make an update query every time user changes something).
now when the user navigates to some different part of your website, refreshes the page or closes the tab, your custom logic is ran.
beforeunload handles refresh and tab close and searchParams triggers useEffect's return part of your code (added comments for explanation)
I wish nextjs documentation had that info but maybe this will help someone as well
So, here's how i handled the trigger when user navigates to some other part of your page and you want to do some custom logic things when user leaves (in my case i wanted to store data in memory until user has finished and then save everything all at once rather than make an update query every time user changes something).
"use client";
import { useSearchParams } from "next/navigation";
const searchParams = useSearchParams();
useEffect(() => {
const handlePageLeave = () => {
// add your custom logic for page leave
};
// this sets up eventlistener on initial mounting
window.addEventListener("beforeunload", handlePageLeave);
// this part triggers when user navigates somewhere else on your page
return () => {
// this calls for your custom logic
handlePageLeave();
// this cleans up eventlistener when the component unmounts
window.removeEventListener("beforeunload", handlePageLeave);
};
}, [searchParams]);now when the user navigates to some different part of your website, refreshes the page or closes the tab, your custom logic is ran.
beforeunload handles refresh and tab close and searchParams triggers useEffect's return part of your code (added comments for explanation)
I wish nextjs documentation had that info but maybe this will help someone as well
usePathname should trigger useEffect though
if not it is a bug.
if not it is a bug.it works just fine.
"use client";
import { usePathname } from "next/navigation";
import { useEffect } from "react";
export function Test() {
const pathname = usePathname();
useEffect(() => {
console.log("Pathname changed to", pathname);
}, [pathname]);
return null;
}wait, perhaps you are doing it on a
page.tsx? won't the page will be unloaded at the time the path changes?Scottish FoldOP
where else would you use it?
people tend to use it on
layout.tsx, as it will live among page routes between different pagesif you're listening to
pathname on the page as the it is being changed, it won't trigger lolScottish FoldOP
that was my point
you have it on
layout.tsx as well?Scottish FoldOP
this should trigger before the page is being changed, regardless if it's in page or layout file
oh I see
Scottish FoldOP
my understanding is that layout files are for the structure of the website and page files are for the content
you would need usePathname in content context and not layout context, so it doesn't make sense to me logically why it would matter in which file it is
"use client";
import Link from "next/link";
import { useEffect } from "react";
export default function Page() {
useEffect(() => {
return () => {
console.log("Navigated away from /");
};
}, []);
return <Link href="/foo">Go to /foo</Link>;
}the return cleanup function is run when the page is unmounted (when you navigate between page.tsx files)
the
should work when you navigate between routes in the same (dynamic route)
the
useEffect(() => {
}, [pathname]);should work when you navigate between routes in the same (dynamic route)
page.tsx file