To detect a route change in Next.js:
appdirectory: useuseEffectandusePathname.pagesdirectory: useuseEffectanduseRouter.
Listen for route/page change in Next.js app directory
To listen for a route change in Next.js 13 app directory, use the useEffect and the usePathname hooks. The action in useEffect will run anytime the pathname from usePathname changes.
'use client';
import { usePathname } from 'next/navigation';
import { useEffect, useState } from 'react';
export function RouteChangeListener() {
const pathname = usePathname();
const [changes, setChanges] = useState(0);
useEffect(() => {
console.log(`Route changed to: ${pathname}`);
setChanges((prev) => prev + 1);
}, [pathname]);
return <></>;
}Here we log to the console and change the state of the component when the route changes.

Page change listener must persist with client-side routing
For this detection to work, the component containing this useEffect needs to be somewhere in the DOM where it will not get unmounted with client-side navigation.
In the Next.js 13 app directory, this could be the layout.tsx file:
import { Metadata } from 'next';
import '@/styles/globals.css';
import { RouteChangeListener } from './route-change-listener';
export const metadata: Metadata = {
title: 'Coding Beauty',
description: 'The official Coding Beauty home page.',
icons: {
icon: '/favicon.png',
},
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
{/* 👇 Persists with client-side navigation */}
<RouteChangeListener />
<body>{children}</body>
</html>
);
}useEffect needs 'use client'
Also, since server components are the default in Next.js 13, you’ll need to add the 'use client' directive at the top of the component file.
Otherwise, you won’t be able to use interactive client-side features like React hooks, including useEffect.

useEffect can’t work without ‘use client’ in Next.js.Listen for route/page change in Next.js pages directory
To handle a URL or location change in Next.js pages directory, combine the useEffect and the useRouter hooks:
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export function UrlChangeListener() {
const router = useRouter();
useEffect(() => {
console.log(`The page is now: ${router.pathname}`);
}, [router]);
return <></>;
}Route change detector must persist with client-side routing
Just like with the app directory, the component that listens for the URL change with useEffect needs to be somewhere in the DOM where it will not get unmounted with client-side navigation.
In the pages directory, this could be the _app.tsx or _app.js file:
import '@/styles/globals.css';
import type { AppProps } from 'next/app';
import { UrlChangeListener } from './url-change-listener';
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<UrlChangeListener />
<Component {...pageProps} />
</>
);
}Detect route/page with useRouter() events
Alternatively, we can detect a client-side URL change in the Next.js pages directory with events that the useRouter() object emits. For example:
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export function UrlChangeListener() {
const router = useRouter();
useEffect(() => {
const startHandler = () => {
console.log('Router change started');
};
const completeHandler = () => {
console.log('Router change completed');
};
router.events.on('routeChangeStart', startHandler);
router.events.on('routeChangeComplete', completeHandler);
return () => {
router.events.off('routeChangeStart', startHandler);
router.events.off('routeChangeComplete', completeHandler);
};
}, []);
// 👇 You can put a progress bar or something here
return <></>;
}Here we used two important router events:
routeChangeStart– fires when the route is about to change.routerChangeComplete– fires when the router has changed completely.
There’s more too, and their names are just as self-explanatory as these two.

Key takeaways
- To listen for a route or page change in Next.js
appdirectory, combine theuseEffectandusePathnamehooks. - Detect a URL change in the
pagesdirectory with theuseEffectanduseRouterhooks. - You can also use the
routeChangeStartandrouteChangeCompleteevents from theuseRouter()object to handle a location change.
11 Amazing New JavaScript Features in ES13
This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.
