#Replace `router.events.on("routeChangeComplete", ...` with app directory.
1 messages · Page 1 of 1 (latest)
Hi @alpine saffron. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
You can listen for page changes in the app directory by using the usePathname and useSearchParams hooks from next/navigation. Here's an example of how to do this:
// app/components/navigation-events.js
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
export function NavigationEvents() {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
const url = pathname + searchParams.toString();
console.log(url);
// You can now use the current URL
// ...
}, [pathname, searchParams]);
return null;
}
Then, import this component into a layout:
// app/layout.js
import { Suspense } from 'react';
import { NavigationEvents } from './components/navigation-events';
export default function Layout({ children }) {
return (
<html lang="en">
<body>
{children}
<Suspense fallback={null}>
<NavigationEvents />
</Suspense>
</body>
</html>
);
}
This will execute the code inside the useEffect hook whenever the page changes, similar to the routeChangeComplete event from next/router.
Source: **https://nextjs.org/docs/app/api-reference/functions/use-router** (https://nextjs.org/docs/app/api-reference/functions/use-router)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@crystal jewel kapa.ai is still learning and improving, please let us how it did by reacting below
@lusty lance Ok, so can you write a version that parametizes the callback from outside so that I can use this utility component everywhere
Let me check the knowledge base for you. One moment! :books:
Sure, you can create a utility component that accepts a callback function as a prop. Here's an example:
// app/components/navigation-events.js
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
export function NavigationEvents({ onRouteChange }) {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (typeof onRouteChange === 'function') {
const url = pathname + searchParams.toString();
onRouteChange(url);
}
}, [pathname, searchParams, onRouteChange]);
return null;
}
Now, you can use this utility component and pass a callback function as a prop:
// app/layout.js
import { Suspense } from 'react';
import { NavigationEvents } from './components/navigation-events';
function handleRouteChange(url) {
console.log('Route changed to:', url);
// Your custom logic here...
}
export default function Layout({ children }) {
return (
<html lang="en">
<body>
{children}
<Suspense fallback={null}>
<NavigationEvents onRouteChange={handleRouteChange} />
</Suspense>
</body>
</html>
);
}
This way, you can reuse the NavigationEvents component and provide different callback functions depending on your needs.
Source: **https://nextjs.org/docs/app/api-reference/functions/use-router** (https://nextjs.org/docs/app/api-reference/functions/use-router)
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@crystal jewel kapa.ai is still learning and improving, please let us how it did by reacting below
@lusty lance write this in Typescript
Let me check the knowledge base for you. One moment! :books:
Sure, here's the TypeScript version of the utility component and its usage:
// app/components/navigation-events.tsx
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
interface NavigationEventsProps {
onRouteChange: (url: string) => void;
}
export function NavigationEvents({ onRouteChange }: NavigationEventsProps) {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (typeof onRouteChange === 'function') {
const url = pathname + searchParams.toString();
onRouteChange(url);
}
}, [pathname, searchParams, onRouteChange]);
return null;
}
Now, you can use this utility component and pass a callback function as a prop:
// app/layout.tsx
import { Suspense } from 'react';
import { NavigationEvents } from './components/navigation-events';
function handleRouteChange(url: string) {
console.log('Route changed to:', url);
// Your custom logic here...
}
interface LayoutProps {
children: React.ReactNode;
}
export default function Layout({ children }: LayoutProps) {
return (
<html lang="en">
<body>
{children}
<Suspense fallback={null}>
<NavigationEvents onRouteChange={handleRouteChange} />
</Suspense>
</body>
</html>
);
}
This TypeScript version of the NavigationEvents component and its usage will provide type safety and better code completion.