We are able to get the docx file running in only office doc editor component but constantly getting the docRef as null due to which we are not able to work.
The document editor shows that the instance already exists and it skips loading, but the docEditorReference returns null.
“use client”;
import { useEffect, useRef, useState, useMemo, useCallback } from “react”;
import “quill/dist/quill.snow.css”;
import * as mammoth from “mammoth”;
import * as htmlDocx from “html-docx-js/dist/html-docx”;
import {
ref as storageRef,
getDownloadURL,
listAll,
} from “firebase/storage”;
import { storage } from “@/lib/firebase”;
import “./quill-fonts.css”;
import { HoverChat } from “./hover-chat”;
import { useAuth } from “@/contexts/auth-context”;
import { useToast } from “@/components/ui/use-toast”;
import { Button } from “@/components/ui/button”;
import { DocumentEditor } from “@onlyoffice/document-editor-react”;
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
} from “@/components/ui/dropdown-menu”;
import { ChevronDown } from “lucide-react”;
export default function EditorTogglePage() {
const editorRef = useRef(null);
const quillRef = useRef(null);
const onlyOfficeRef = useRef(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [activeEditor, setActiveEditor] = useState<“quill” | “onlyoffice”>(“quill”);
const { user } = useAuth();
const { toast } = useToast();
const [token, setToken] = useState<string | null>(null);
const [editorReady, setEditorReady] = useState(false);
const [showSaveDialog, setShowSaveDialog] = useState(false);
const [savedFileName, setSavedFileName] = useState(“”);
const [hoverChat, setHoverChat] = useState(null);
const searchParams = typeof window !== “undefined” ? new URLSearchParams(window.location.search) : null;
const docUrl = searchParams?.get(“file”) || null;
const docSessionKey = useMemo(() => {
if (!docUrl) return new-doc-${Date.now()}
;
const baseKey = btoa(docUrl).slice(0, 20).replace(/[^a-zA-Z0-9]/g, “”);
return doc-${baseKey}-${Date.now()}
;
}, [docUrl]);
function getFileNameFromUrl(url: string | null) {
if (!url) return “”;
try {
const decoded = decodeURIComponent(url);
const lastSegment = decoded.split(“/”).pop() || “”;
return lastSegment.split(“?”)[0];
} catch {
return “”;
}
}
// Quill Editor Initialization
useEffect(() => {
if (activeEditor !== “quill”) return;
const initializeEditor = async () => {
try {
const Quill = (await import(“quill”)).default;
const FontAttributor: any = Quill.import(“attributors/class/font”);
FontAttributor.whitelist = [“arial”, “times-new-roman”, “verdana”];
Quill.register(FontAttributor, true);
if (!editorRef.current) return;
quillRef.current = new Quill(editorRef.current, {
theme: "snow",
modules: {
toolbar: [
[{ header: [1, 2, 3, false] }],
[{ font: FontAttributor.whitelist }],
["bold", "italic", "underline", "strike"],
["blockquote", "code-block"],
[{ list: "ordered" }, { list: "bullet" }],
[{ align: [] }],
["link", "image"],
["clean"],
],
},
});
} catch (e) {
setError("Failed to load editor");
} finally {
setLoading(false);
}
};
initializeEditor();
}, [activeEditor]);
// UI
return (
<Button onClick={() => toast({ title: “Save Clicked” })} variant=“primary” size=“sm”>Save
<Button onClick={() => setActiveEditor(“quill”)} variant={activeEditor === “quill” ? “default” : “outline”} size=“sm”>Quill
<Button onClick={() => setActiveEditor(“onlyoffice”)} variant={activeEditor === “onlyoffice” ? “default” : “outline”} size=“sm”>OnlyOffice
Document
<DropdownMenuItem onClick={() => toast({ title: “Version 1” })}>Version 1
<DropdownMenuItem onClick={() => toast({ title: “Version 2” })}>Version 2
<div className="flex-1 min-h-0 flex flex-col">
{activeEditor === "quill" && (
<div ref={editorRef} style={{ height: "100%", minHeight: 0, border: "1px solid #ccc", flex: 1 }} />
)}
{activeEditor === "onlyoffice" && (
<div style={{ height: "100%", minHeight: 0, flex: 1 }}>
<DocumentEditor
id="onlyoffice-editor"
key={docSessionKey}
documentServerUrl="YOUR_DOCUMENT_SERVER_URL"
config={{
document: {
fileType: "docx",
key: docSessionKey,
title: getFileNameFromUrl(docUrl),
url: docUrl || "",
permissions: { edit: true, download: true },
},
editorConfig: {
user: {
id: user?.uid || "anonymous",
name: user?.displayName || "User",
},
customization: {
autosave: true,
forcesave: true,
uiTheme: "dark",
},
},
token,
width: "100%",
height: "100%",
}}
onLoad={(editor) => {
onlyOfficeRef.current = editor;
setEditorReady(true);
}}
/>
</div>
)}
</div>
{showSaveDialog && (
<div className="fixed inset-0 flex items-center justify-center z-50 bg-black/30">
<div className="bg-white dark:bg-gray-900 rounded-lg shadow-lg p-6 min-w-[300px] flex flex-col items-center">
<span className="text-2xl mb-2">✅</span>
<div className="font-semibold mb-1">Document Saved!</div>
<div className="text-xs text-muted-foreground mb-2">{savedFileName}</div>
<div className="text-sm text-gray-500">Reloading...</div>
</div>
</div>
)}
</div>
);
}