Reputation: 341
I'm trying to cancel the routing change when the user leaves the page without saving changes. To achieve this in Next.js, I need to listen to routing changes and cancel them using a handler function as middleware to intercept the route change
Like this:
import { Router } from 'next/router'
Router.events.on('routeChangeStart', handleChange)
in order to listen and emit a handler function as middleware to intercept the route changing
I know NextJS introduced a new Router inside "next/navigation". However when I attempt to import the legacy Router from "next/router" like this:
import SingletonRouter from 'next/router';
the singleton shows a null
.
I need to access that singleton in order to prevent routing changes.
I need to access that Router singleton in order to prevent routing changes.
Upvotes: 1
Views: 334
Reputation: 26
pages
directoriesYou will be able to access the Router
legacy hook module from 'next/router"
but to access SingletonRouter
to emit events, you must use pages
folder structure for routing instead of the app
folders.
The new Router
from 'next/navigation" does not allow you to prevent the routing.
As a workaround, I found that some Next.js projects mix the pages folder and app folder, but I do not recommend this approach.
Here is a example of a repository that is accesses SingletonRouter
using pages
with Nextjs 13:
Upvotes: 1
Reputation: 278
First.. If you use app router. You need to use next/navigation. If you use the pages directory, you can use the next/router package.
Set up state to track changes: First, manage a state variable that tracks whether there are unsaved changes.
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
function YourComponent() {
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
const router = useRouter();
const toggleUnsavedChanges = () => setHasUnsavedChanges(!hasUnsavedChanges);
}
Use the beforePopState method to intercept route changes. You can prompt the user with a confirmation dialog to ensure they want to leave the page with unsaved changes.
useEffect(() => {
const handleRouteChange = (url) => {
if (router.asPath !== url && hasUnsavedChanges) {
if (window.confirm('You have unsaved changes, are you sure you want to leave?')) {
// Allow the route change
return true;
} else {
// Prevent the route change
router.events.emit('routeChangeError');
throw 'Route change aborted.';
}
}
}
router.beforePopState(handleRouteChange);
return () => {
router.beforePopState(() => true); // Clean up the listener
};
}, [hasUnsavedChanges, router]);
You’ll need to adjust the state based on user interactions that affect whether there are unsaved changes. For instance, modifying a form field would set hasUnsavedChanges to true.
Upvotes: 1