#Replace `router.events.on("routeChangeComplete", ...` with app directory.

1 messages · Page 1 of 1 (latest)

alpine saffron
#

How can I execute code when page transition occurs using the app directory. I used to rely onrouter.events.on("routeChangeComplete", ... from next/router, but the new next/navigation doesn't include this functionality.

lusty lanceBOT
#

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

alpine saffron
#

@lusty lance Ok, so can you write a version that parametizes the callback from outside so that I can use this utility component everywhere

lusty lanceBOT
#

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

alpine saffron
#

@lusty lance write this in Typescript

lusty lanceBOT
#

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.

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: