Popup when detected adblock breaking onlyoffice
All checks were successful
Automated Container Build / build-and-push (push) Successful in 32s

This commit is contained in:
Elijah Kuntz 2026-06-11 11:36:27 -07:00
parent c8ea7f3d88
commit 4bcd3efa11

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState, useRef } from 'react';
import React, { useEffect, useState, useRef, useCallback } from 'react';
import { DocumentEditor } from '@onlyoffice/document-editor-react';
import { Sun, Moon, Loader2, ArrowLeft, RefreshCw, Download } from 'lucide-react';
import { Sun, Moon, Loader2, ArrowLeft, RefreshCw, Download, ShieldAlert, X } from 'lucide-react';
import api from '@/lib/api';
import { FileItem } from '@/types/files';
@ -18,6 +18,10 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
const [loadError, setLoadError] = useState<string | null>(null);
const [config, setConfig] = useState<any>(null);
const [isRenaming, setIsRenaming] = useState(false);
const [adblockWarning, setAdblockWarning] = useState(false);
const [documentReady, setDocumentReady] = useState(false);
const documentReadyRef = useRef(false);
const loadTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const extMatch = file.name.match(/\.[^.]+$/);
const ext = extMatch ? extMatch[0] : '';
@ -130,9 +134,39 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
const docServerUrl = process.env.NEXT_PUBLIC_ONLYOFFICE_URL || 'https://office.elijahkuntz.com/';
const onDocumentReady = function (event: any) {
// Proactively detect if an adblocker is blocking OnlyOffice resources
useEffect(() => {
if (!config) return;
// Test fetch for a resource commonly blocked by adblockers (Brave Shields, uBlock, etc.)
const testUrl = `${docServerUrl}web-apps/apps/common/Analytics.js`;
fetch(testUrl, { method: 'HEAD', mode: 'no-cors' })
.then(() => {
// mode: 'no-cors' always resolves — check with a timeout fallback instead
})
.catch(() => {
setAdblockWarning(true);
});
// Fallback: if onDocumentReady hasn't fired in 8s, show the warning
loadTimeoutRef.current = setTimeout(() => {
if (!documentReadyRef.current) {
setAdblockWarning(true);
}
}, 8000);
return () => {
if (loadTimeoutRef.current) clearTimeout(loadTimeoutRef.current);
};
}, [config, docServerUrl]);
const onDocumentReady = useCallback(function (event: any) {
console.log("Document is loaded");
};
documentReadyRef.current = true;
setDocumentReady(true);
setAdblockWarning(false);
if (loadTimeoutRef.current) clearTimeout(loadTimeoutRef.current);
}, []);
const onLoadComponentError = function (errorCode: number, errorDescription: string) {
setLoadError(`${errorCode}: ${errorDescription}`);
@ -192,16 +226,44 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
</div>
<div className="flex-1 relative">
{loadError ? (
<div className="absolute inset-0 flex items-center justify-center bg-gray-50 text-red-600 p-8 text-center flex-col">
<div className="absolute inset-0 flex items-center justify-center bg-gray-50 dark:bg-[#1a1a1a] p-8 text-center flex-col">
<svg className="w-12 h-12 mb-4 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<h3 className="font-bold text-lg mb-2">Failed to load OnlyOffice Editor</h3>
<p className="text-sm">{loadError}</p>
<p className="mt-4 text-xs text-gray-500">Check if your OnlyOffice server is running and accessible at the configured URL.</p>
<h3 className="font-bold text-lg mb-2 text-red-600 dark:text-red-400">Failed to load OnlyOffice Editor</h3>
<p className="text-sm text-red-600 dark:text-red-400">{loadError}</p>
<p className="mt-4 text-xs text-gray-500 dark:text-gray-400">Check if your OnlyOffice server is running and accessible at the configured URL.</p>
</div>
) : (
<div className="absolute inset-0">
{/* Adblocker / Brave Shields warning banner */}
{adblockWarning && !documentReady && (
<div className="absolute top-0 left-0 right-0 z-50 flex items-start gap-3 px-5 py-4 bg-amber-50 dark:bg-amber-950/80 border-b border-amber-200 dark:border-amber-800 shadow-lg animate-in slide-in-from-top">
<ShieldAlert className="w-6 h-6 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-semibold text-sm text-amber-800 dark:text-amber-200">Ad Blocker Detected</h4>
<p className="text-xs text-amber-700 dark:text-amber-300 mt-1 leading-relaxed">
Your ad blocker or browser shield is blocking resources required by the document editor.
The editor may not load or function correctly.
</p>
<div className="mt-2 text-xs text-amber-600 dark:text-amber-400 space-y-1">
<p className="font-medium">To fix this:</p>
<ul className="list-disc list-inside space-y-0.5 ml-1">
<li><strong>Brave:</strong> Click the Shields icon (lion) in the address bar set Shields to <em>Down</em> for this site</li>
<li><strong>uBlock / AdBlock:</strong> Click the extension icon disable for this site</li>
</ul>
<p className="mt-1.5">Then refresh the page.</p>
</div>
</div>
<button
onClick={() => setAdblockWarning(false)}
className="p-1 rounded-md hover:bg-amber-200/50 dark:hover:bg-amber-800/50 transition-colors flex-shrink-0"
title="Dismiss"
>
<X className="w-4 h-4 text-amber-600 dark:text-amber-400" />
</button>
</div>
)}
<DocumentEditor
id="docxEditor"
documentServerUrl={docServerUrl}