I’m working on a React application where I need to prevent users from switching tabs or applications when certain conditions are met. Specifically, I’m using the Visibility API
to detect when the user switches tabs and the blur
event to detect when the user switches to another application. I also attempt to block key combinations like Ctrl + Tab
and Alt + Tab
using a keydown
event listener.
Here’s my code:
import { useEffect, useRef } from "react";
import { toast } from "@/utils/toast";
interface Props {
isDisabled: boolean;
}
const DisableTabSwitch: React.FC<Props> = ({ isDisabled }) => {
const listenersAdded = useRef(false);
const tabSwitchCount = useRef(0);
useEffect(() => {
if (isDisabled && !listenersAdded.current) {
listenersAdded.current = true;
// Handle when the user switches tabs (using the Visibility API)
const handleVisibilityChange = () => {
if (document.visibilityState === "hidden") {
tabSwitchCount.current += 1;
toast.error(
"Tab switching is not allowed. Please stay on the current tab. Your session is being recorded.",
{ duration: 3000, position: "top-right" }
);
window.focus();
}
};
// Handle when the window loses focus (user switches away from the current app)
const handleWindowBlur = () => {
tabSwitchCount.current += 1;
toast.error(
"Please stay on this window. Switching applications is not allowed.",
{ duration: 3000, position: "top-right" }
);
window.focus();
};
// Handle specific keyboard shortcuts that allow switching between tabs/applications
const handleKeyboardEvent = (event: KeyboardEvent) => {
if (
(event.ctrlKey && event.key === "Tab") || // Ctrl + Tab (Windows/Linux)
(event.altKey && event.key === "Tab") || // Alt + Tab (Windows/Linux)
(event.metaKey && event.key === "Tab") || // Cmd + Tab (macOS)
(event.shiftKey && event.key === "Tab") // Shift + Tab
) {
event.preventDefault();
toast.error(
"Keyboard shortcuts for tab/application switching are disabled during the session.",
{ duration: 3000, position: "top-right" }
);
window.focus();
}
};
// Attach event listeners
document.addEventListener("visibilitychange", handleVisibilityChange, true);
window.addEventListener("blur", handleWindowBlur, true);
window.addEventListener("keydown", handleKeyboardEvent, true);
// Clean up event listeners when the component is unmounted or toggled off
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange, true);
window.removeEventListener("blur", handleWindowBlur, true);
window.removeEventListener("keydown", handleKeyboardEvent, true);
listenersAdded.current = false;
};
}
}, [isDisabled]);
return null;
};
export default DisableTabSwitch;
This works to an extent, as I can detect when the tab or application switch happens. However, I’m still able to switch tabs using Ctrl + Tab
(on Windows) and switch applications with Alt + Tab
, or Cmd + Tab
on macOS. I want to block these actions during the session but understand that browser security restrictions limit what can be done.
My questions are:
- Is there any way to more reliably prevent tab and application switching in modern browsers?
- Are there other ways to detect and discourage tab/application switching that I haven’t considered?
- How can I block or prevent these actions in a more secure way, or at least track them more effectively?
Thanks for any suggestions!