const DevToolsDetector = { checkWindowSize() { const threshold = 160; return ( window.outerWidth - window.innerWidth > threshold || window.outerHeight - window.innerHeight > threshold ); }, checkConsole() { let detected = false; const element = new Image(); Object.defineProperty(element, 'id', { get: () => { detected = true; } }); console.log('%c', element); console.clear(); return detected; }, checkDebugger() { if (import.meta.env.DEV) return false; const start = performance.now(); // eslint-disable-next-line no-debugger debugger; const end = performance.now(); return end - start > 100; }, checkToString() { let detected = false; const div = document.createElement('div'); Object.defineProperty(div, 'id', { get: function () { detected = true; return 'id'; } }); console.log(div); console.clear(); return detected; }, detect() { return ( this.checkWindowSize() || this.checkConsole() || this.checkDebugger() || this.checkToString() ); } }; export default DevToolsDetector; import { useEffect, useState } from 'react'; const isMobileOrIOS = () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); export const useDevToolsDetection = (onDetected) => { const [isBlocked, setIsBlocked] = useState(false); useEffect(() => { if (isMobileOrIOS()) return; const interval = setInterval(() => { const detected = DevToolsDetector.detect(); if (detected && !isBlocked) { setIsBlocked(true); onDetected?.(); } else if (!detected && isBlocked) { setIsBlocked(false); clearInterval(interval); setTimeout(() => window.location.reload(), 100); } }, 1000); return () => clearInterval(interval); }, [isBlocked]); return isBlocked; };