Skip to content

Instantly share code, notes, and snippets.

@isocroft
Created February 26, 2024 20:24
Show Gist options
  • Save isocroft/26ca9fd61e409d85019b981506d73ba1 to your computer and use it in GitHub Desktop.
Save isocroft/26ca9fd61e409d85019b981506d73ba1 to your computer and use it in GitHub Desktop.
A custom NextJS hook for handling unsaved changes in a browser application
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
export const useNextJSUnsavedChangesLock = ({
promptText = "You have unsaved changes - are you sure you wish to leave this page?",
useBrowserPrompt = true,
unsavedChangesStatus = false
}: { promptText: string, useBrowserPrompt?: boolean, unsavedChangesStatus?: boolean }) => {
const router = useRouter();
router.beforePopState((state) => {
return false;
});
const hasUnsavedChanges = unsavedChangesStatus;
const warningText = promptText;
const [unsavedChanges, setUnsavedChanges] = useState(() => hasUnsavedChanges || false);
useEffect(() => {
const handleWindowClose = (e: BeforeUnloadEvent) => {
if (!unsavedChanges) return
e.preventDefault()
return (e.returnValue = warningText);
}
const handleBrowseAway = () => {
if (!unsavedChanges) return
if (useBrowserPrompt || false) {
if (window.confirm(warningText)) return
}
router.events.emit('routeChangeError');
throw 'routeChange aborted.';
};
window.addEventListener('beforeunload', handleWindowClose);
router.events.on('routeChangeStart', handleBrowseAway);
return () => {
window.removeEventListener('beforeunload', handleWindowClose)
router.events.off('routeChangeStart', handleBrowseAway)
};
}, [unsavedChanges]);
return {
setUnsavedChanges
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment