npm install @harbour-enterprises/superdoc
// components/DocumentEditor.jsx
import { useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
// Prevent SSR issues
const DocumentEditor = dynamic(
() => Promise.resolve(DocumentEditorComponent),
{ ssr: false }
);
function DocumentEditorComponent({ document }) {
const containerRef = useRef(null);
const superdocRef = useRef(null);
useEffect(() => {
const initEditor = async () => {
const { SuperDoc } = await import('@harbour-enterprises/superdoc');
if (containerRef.current) {
superdocRef.current = new SuperDoc({
selector: containerRef.current,
document
});
}
};
initEditor();
return () => {
superdocRef.current = null;
};
}, [document]);
return <div ref={containerRef} style={{ height: '700px' }} />;
}
export default DocumentEditor;
// app/editor/page.jsx
'use client';
import dynamic from 'next/dynamic';
const DocumentEditor = dynamic(
() => import('@/components/DocumentEditor'),
{
ssr: false,
loading: () => <div>Loading editor...</div>
}
);
export default function EditorPage() {
return (
<main>
<DocumentEditor document="/sample.docx" />
</main>
);
}
// pages/api/documents/[id].js (Pages Router)
// app/api/documents/[id]/route.js (App Router)
export async function GET(request, { params }) {
const docId = params.id;
// Fetch document from storage
const document = await fetchDocumentFromStorage(docId);
return new Response(document, {
headers: {
'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
}
});
}
// components/SecureEditor.jsx
import { useSession } from 'next-auth/react';
import dynamic from 'next/dynamic';
const DocumentEditor = dynamic(() => import('./DocumentEditor'), { ssr: false });
export default function SecureEditor() {
const { data: session, status } = useSession();
if (status === 'loading') return <div>Loading...</div>;
if (!session) return <div>Please sign in</div>;
return (
<DocumentEditor
document="/protected-doc.docx"
user={{
name: session.user.name,
email: session.user.email
}}
/>
);
}