Skip to content

Instantly share code, notes, and snippets.

@srph
Last active July 22, 2026 18:38
Show Gist options
  • Select an option

  • Save srph/9b6170eb209090298d609e51fdb92872 to your computer and use it in GitHub Desktop.

Select an option

Save srph/9b6170eb209090298d609e51fdb92872 to your computer and use it in GitHub Desktop.
Next: useUnsavedChanges - A super basic boilerplate wrapping Next.js route abort events

what

A super basic boilerplate wrapping Next.js route abort events

usage

useUnsavedChangesWarning(form.isDirty === true && status !== 'pending')
import { useEffect } from "react";
import { useRouter } from "next/router";
export function useUnsavedChangesWarning(hasUnsavedChanges: boolean) {
const router = useRouter();
useEffect(() => {
const handleRouteChangeStart = (url: string) => {
if (hasUnsavedChanges && router.asPath !== url) {
const confirmed = confirm(
"You have unsaved changes that will be lost. Are you sure you want to leave?",
);
if (!confirmed) {
router.events.emit("routeChangeError");
throw "Route change aborted by user";
}
}
};
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (hasUnsavedChanges) {
event.preventDefault();
event.returnValue = "You have unsaved changes that will be lost.";
}
};
if (hasUnsavedChanges) {
router.events.on("routeChangeStart", handleRouteChangeStart);
window.addEventListener("beforeunload", handleBeforeUnload);
}
return () => {
router.events.off("routeChangeStart", handleRouteChangeStart);
window.removeEventListener("beforeunload", handleBeforeUnload);
};
}, [hasUnsavedChanges, router]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment