Skip to main content

React

The ONLYOFFICE Docs React component integrates ONLYOFFICE Docs into React projects. The component supports React 16.9 and later, including React 19. The list of changes for each version is published on the Releases tab.

Prerequisites​

This procedure requires Node.js (and npm) and a running ONLYOFFICE Docs instance. If you do not have one, install it on your own server as described in the self-hosted section, or deploy it in the cloud.

It also requires the secret key of your ONLYOFFICE Docs. The editor configuration is validated with a JSON Web Token signed with this key, and the validation is enabled by default. See Signing the configuration.

The page assumes a basic working knowledge of React. The component works in any React project. The steps below use Vite to create one from scratch.

Creating the demo React application with ONLYOFFICE Docs editor​

This procedure creates a basic React application and installs an ONLYOFFICE Docs editor in it.

  1. Create a new React project named onlyoffice-react-demo and install its dependencies:

    npm create vite@latest onlyoffice-react-demo -- --template react
    cd onlyoffice-react-demo
    npm install
  2. Install the ONLYOFFICE Docs React component from the npm public registry, together with the jsonwebtoken package that signs the editor configuration, and save them to the package.json file.

    TypeScript declarations come from the @onlyoffice/doceditor-types peer dependency, which npm 7 and later installs automatically and yarn does not. The jsonwebtoken package runs in the development server only, so it is a development dependency of the demo application. In a production application, it belongs to the backend that signs the configuration.

    npm install --save @onlyoffice/document-editor-react
    npm install --save-dev jsonwebtoken
  3. Replace the contents of the ./src/App.jsx and ./vite.config.js files in the onlyoffice-react-demo project, and create the ./.env.local file:

    The App component, which requests the signed configuration when it mounts and renders the ONLYOFFICE Docs editor once the configuration arrives. The config property is required, so the component returns null until then.

    The editor fills the element it is rendered into, so the wrapper gives it an explicit height.

    import {DocumentEditor} from "@onlyoffice/document-editor-react";
    import {useEffect, useState} from "react";

    function onDocumentReady() {
    console.log("Document is loaded");
    }

    function onLoadComponentError(errorCode, errorDescription) {
    switch (errorCode) {
    case -1: // Unknown error loading component
    console.log(errorDescription);
    break;

    case -2: // Error load DocsAPI from documentServerUrl
    console.log(errorDescription);
    break;

    case -3: // DocsAPI is not defined
    console.log(errorDescription);
    break;
    }
    }

    export default function App() {
    const [config, setConfig] = useState(null);

    useEffect(() => {
    fetch("/api/editor-config")
    .then((response) => response.json())
    .then(setConfig);
    }, []);

    if (!config) return null; // the configuration is not loaded yet

    return (
    <div style={{display: "flex", height: "100svh"}}>
    <DocumentEditor
    id="docxEditor"
    documentServerUrl={import.meta.env.VITE_DOCUMENT_SERVER_URL}
    config={config}
    events_onDocumentReady={onDocumentReady}
    onLoadComponentError={onLoadComponentError}
    />
    </div>
    )
    }
  4. Start the Vite development server in the onlyoffice-react-demo directory:

    npm run dev

    Open http://localhost:5173 in the browser. The editor opens the document from the signed configuration, and the events_onDocumentReady handler prints Document is loaded to the browser console.

Signing the configuration​

ONLYOFFICE Docs validates the editor configuration with a JSON Web Token. JWT validation is enabled by default, so the config must include a token — a signature of the configuration itself. The token is not a constant: regenerate it whenever any signed parameter changes.

Signing requires the secret key of your ONLYOFFICE Docs, so generate the token on your server and send the ready configuration to the browser. A React application cannot keep the secret key private.

The component merges config into the configuration it sends to ONLYOFFICE Docs, so the token field reaches the editor unchanged.

The demo application above signs the configuration in the Vite development server, which exists in development only. In a production application, move the same code to your backend and keep the endpoint path, as the component requests the configuration in the same way.

See the Signature section for the signing code in other languages.

Calling editor methods in the React component​

The component stores every editor instance in the window.DocEditor.instances object. Get the instance by the component id, then call any editor method from it:

function onDocumentReady() {
const documentEditor = window.DocEditor.instances["docxEditor"];

documentEditor.showMessage("Welcome to ONLYOFFICE Editor!");
}

Using Automation API in React​

Automation API interacts with the document content from your own interface through a connector. A connector is bound to the editor instance that created it and remains valid as long as this instance exists.

info

Automation API is available only for ONLYOFFICE Docs Developer.

Create the connector with the createConnector method in the events_onDocumentReady handler, and reuse it instead of creating a new one for each operation. Store it in a ref for the cleanup and in the state for the components that use it:

import {DocumentEditor} from "@onlyoffice/document-editor-react";
import {useEffect, useRef, useState} from "react";

export default function Editor({config}) {
const [connector, setConnector] = useState(null);
const connectorRef = useRef(null);

const onDocumentReady = () => {
const documentEditor = window.DocEditor.instances["docxEditor"];
const created = documentEditor.createConnector();

connectorRef.current = created; // for the cleanup
setConnector(created); // for the components that use the connector
};

useEffect(() => {
return () => {
connectorRef.current?.disconnect();
connectorRef.current = null;
};
}, []);

return (
<div style={{display: "flex", height: "100svh"}}>
<DocumentEditor
id="docxEditor"
documentServerUrl="http://documentserver/"
config={config}
events_onDocumentReady={onDocumentReady}
/>
</div>
)
}

Call the disconnect method in the cleanup function of the component that renders DocumentEditor, so that the connector is disconnected while the editor still exists.

Check that the connector is created before sending commands through it instead of retrying the failed calls:

useEffect(() => {
if (!connector) return; // the editor is not ready yet

connector.executeMethod("GetAllComments", null, (comments) => {
console.log("Comments:", comments);
});
}, [connector]);

executeMethod runs one editor method by name, as above. callCommand runs a function of Office JavaScript API commands inside the editor, which is how the content of the document is changed. That function has a context of its own and cannot read the component state, so pass the data it needs through the Asc.scope object:

function insertText(text) {
if (!connector) return;

Asc.scope.text = text; // the command below has a context of its own

connector.callCommand(() => {
const document = Api.GetDocument();
const paragraph = Api.CreateParagraph();

paragraph.AddText(Asc.scope.text);
document.InsertContent([paragraph]);
}, () => {
console.log("Text is inserted");
});
}
note

The component destroys the editor when it is unmounted and when the documentServerUrl, config, document_fileType, document_title, documentType, editorConfig_lang, height, type, or width property changes, and then loads a new editor. The connector of the destroyed editor becomes invalid: disconnect it and create a new one in the events_onDocumentReady handler of the new editor.

Deploying the demo React application​

note

The /api/editor-config endpoint is a part of the Vite development server, so it does not exist in the production build. Serve the endpoint from your own backend, as described in Signing the configuration, and keep the path that App.jsx requests.

Create a production build in the onlyoffice-react-demo directory and check it locally with the Vite preview server:

npm run build
npm run preview

The build goes to the dist directory. To deploy the application to your own web server, copy the contents of this directory to the root directory of the web server.

Using the component with Next.js​

The component renders the editor in the browser and does not contain the "use client" directive. The editor configuration also includes event handler functions, which cannot be passed from a server component. For these reasons, render the component from a client component.

In the App Router, sign the configuration in a route handler, which runs on the server, and request it from a client component:

The client component, which carries the "use client" directive, requests the signed configuration, and renders the editor once the configuration arrives.

"use client";

import {DocumentEditor} from "@onlyoffice/document-editor-react";
import {useEffect, useState} from "react";

export default function Editor() {
const [config, setConfig] = useState(null);

useEffect(() => {
fetch("/api/editor-config")
.then((response) => response.json())
.then(setConfig);
}, []);

if (!config) return null;

return (
<div style={{display: "flex", height: "100svh"}}>
<DocumentEditor
id="docxEditor"
documentServerUrl="http://documentserver/"
config={config}
events_onDocumentReady={() => console.log("Document is loaded")}
/>
</div>
)
}

A server component can also build the configuration and pass it to the client component as a prop, but the event handlers stay in the client component: functions cannot be passed from a server component.

Server rendering does not require any additional settings: the component renders an empty container on the server and loads the ONLYOFFICE Docs API script after hydration. Importing the component with next/dynamic and the {ssr: false} option is only needed to exclude it from prerendering completely. In the App Router, this option is available in client components only.

To deploy the application, use the next start command. A static build with the output: "export" option cannot run route handlers, so it needs the endpoint served by a separate backend.

Properties​

The config property is merged over the separate properties of the component. The merge is shallow: a top-level key of config replaces the corresponding component properties entirely instead of merging with them.

  • If config.document is set, the document_fileType and document_title properties are ignored.
  • If config.editorConfig is set, the editorConfig_lang property is ignored.
  • If config.events is set, all the events_on* properties are ignored.

Each events_on* property corresponds to the event with the same name in the editor configuration.

NameTypeDefaultDescription
id*string-Component unique identifier.
documentServerUrl*string-Address of ONLYOFFICE Docs.
config*object-Generic configuration object for opening a file.
shardkeystring | booleantrueThe shardkey parameter added to the query string of the ONLYOFFICE Docs API script request for load balancing. If set to true, the document key from config is used as a value. Set to false to send the request without this parameter.
onLoadComponentError(errorCode: number, errorDescription: string) => voidnullThe function called when an error occurs while loading a component.
document_fileTypestringnullThe type of the file.
document_titlestringnullThe file name.
documentTypestringnullThe document type.
editorConfig_langstringnullThe editor interface language.
heightstringnullThe document height in the browser window.
typestringnullThe platform type used to access the document: desktop, mobile, or embedded.
widthstringnullThe document width in the browser window.
events_onAppReady(event: object) => voidnullThe function called when the application is loaded into the browser.
events_onDocumentStateChange(event: object) => voidnullThe function called when the document is modified.
events_onMetaChange(event: object) => voidnullThe function called when the meta information of the document is changed via the meta command.
events_onDocumentReady(event: object) => voidnullThe function called when the document is loaded into the document editor.
events_onInfo(event: object) => voidnullThe function called when the application opened the file.
events_onWarning(event: object) => voidnullThe function called when a warning occurs.
events_onError(event: object) => voidnullThe function called when an error or some other specific event occurs.
events_onRequestSharingSettings(event: object) => voidnullThe function called when the user is trying to manage document access rights by clicking Change access rights button.
events_onRequestRename(event: object) => voidnullThe function called when the user is trying to rename the file by clicking the Rename... button.
events_onRequestInsertImage(event: object) => voidnullThe function called when the user is trying to insert an image by clicking the Image from Storage button.
events_onRequestSaveAs(event: object) => voidnullThe function called when the user is trying to save file by clicking Save Copy as... button.
events_onRequestMailMergeRecipients(event: object) => voidnullDeprecated since version 7.5, use events_onRequestSelectSpreadsheet instead. The function called when the user is trying to select recipients data by clicking the Mail merge button.
events_onRequestCompareFile(event: object) => voidnullDeprecated since version 7.5, use events_onRequestSelectDocument instead. The function called when the user is trying to select document for comparing by clicking the Document from Storage button.
events_onRequestEditRights(event: object) => voidnullThe function called when the user is trying to switch the document from the viewing into the editing mode by clicking the Edit Document button.
events_onRequestHistory(event: object) => voidnullThe function called when the user is trying to show the document version history by clicking the Version History button.
events_onRequestHistoryClose(event: object) => voidnullThe function called when the user is trying to go back to the document from viewing the document version history by clicking the Close History button.
events_onRequestHistoryData(event: object) => voidnullThe function called when the user is trying to click the specific document version in the document version history.
events_onRequestRefreshFile(event: object) => voidnullThe function called when the file must be updated in the editor without reloading the page.
events_onRequestRestore(event: object) => voidnullThe function called when the user is trying to restore the file version by clicking the Restore button in the version history.
events_onRequestSelectSpreadsheet(event: object) => voidnullThe function called when the user is trying to select recipients data by clicking the Mail merge button.
events_onRequestSelectDocument(event: object) => voidnullThe function called when the user is trying to select a document for comparing, combining, or inserting text.
events_onRequestUsers(event: object) => voidnullThe function called when the user can select other users to mention in the comments, grant the access rights to edit the specific sheet ranges, or set the user avatars.

* - required field

Feedback and support​

In case you have any issues, questions, or suggestions for the ONLYOFFICE Docs React component, please refer to the Issues section.