useBeforeUnload
A React hook that listens for the `beforeunload` event.
Example
import { useState } from "react";
import useBeforeUnload from "@/hooks/useBeforeUnload";
export default function UseBeforeUnloadExample() {
const [isEnabled, setIsEnabled] = useState(true);
useBeforeUnload(isEnabled, "Hello from beforeunload");
return (
<div className="flex flex-col items-center justify-center gap-4 p-4">
<p className="text-ctp-text">{isEnabled ? "Enabled" : "Disabled"}</p>
<a href="https://example.com" className="text-ctp-blue underline">
Quit this page
</a>
<div className="flex flex-row items-center justify-center gap-4 p-4">
<button
className="rounded bg-ctp-green px-4 py-2 text-ctp-base"
onClick={() => setIsEnabled(true)}
>
Enable
</button>
<button
className="rounded bg-ctp-red px-4 py-2 text-ctp-base"
onClick={() => setIsEnabled(false)}
>
Disable
</button>
</div>
</div>
);
}
Code
import { useCallback, useEffect } from "react";
/**
* A React hook that listens for the `beforeunload` event.
*
* @param {boolean} enabled - A boolean or a function that returns a boolean. If the
* function returns `false`, the event will be prevented.
* @param {string | undefined} message - An optional message to display in the dialog.
*/
export default function (
enabled: boolean | (() => boolean) = true,
message?: string,
) {
const handler = useCallback(
(event: BeforeUnloadEvent) => {
const finalEnabled = typeof enabled === "function" ? enabled() : true;
if (!finalEnabled) {
return;
}
event.preventDefault();
if (message) {
event.returnValue = message;
}
return message;
},
[enabled, message],
);
useEffect(() => {
if (!enabled) {
return;
}
window.addEventListener("beforeunload", handler);
return () => window.removeEventListener("beforeunload", handler);
}, [enabled, handler]);
}