Connect to an Office document
Embed an Office iframe, connect @thinkfree.dev/tfo-sdk to it, wait for the editor, and read the active document.
Result: the SDK connects to the iframe and returns data from the open document.
Before you begin
- Install Node.js and npm.
- Prepare an Office document-open URL for a Word, Spreadsheet, or Presentation document.
- Confirm the host page can embed that Office origin.
- Use an HTTPS origin in deployed environments.
Install the public npm package @thinkfree.dev/tfo-sdk in your project directory.
npm install @thinkfree.dev/tfo-sdk
For a plain HTML page, add this import map to the <head> of index.html to load the installed ESM files. Put the later JavaScript examples in order inside a <script type="module"> after the iframe. Bundler projects can import the package by name without an import map.
<script type="importmap">
{"imports":{"@thinkfree.dev/tfo-sdk":"./node_modules/@thinkfree.dev/tfo-sdk/dist/index.js"}}
</script>
With Python 3 installed, run this command from the project directory and open http://localhost:3000.
Do not open the HTML directly with file://.
python3 -m http.server 3000 --bind 127.0.0.1
1. Embed the editor
<iframe
id="office-frame"
title="Thinkfree Office document"
src="YOUR_OFFICE_DOCUMENT_OPEN_URL"
></iframe>
The open URL is issued by your Office/storage integration. The SDK does not create it.
2. Connect to the editor
Call the entry point that matches the document type of the open URL - Office.word, Office.cell (Spreadsheet), or
Office.show (Presentation).
import { Office } from "@thinkfree.dev/tfo-sdk";
const iframe = document.querySelector("#office-frame");
const word = Office.word(iframe); // origin is derived from iframe.src
The editor origin must be exact and cannot be *. The SDK ignores messages from any other origin. If the iframe has no
src yet, or uses a data:/blob: URL, pass the origin explicitly: Office.word(iframe, { frameworkOrigin }).
3. Wait for the editor and read the document
whenReady() polls the editor until its SDK bridge answers, so you can call it right after the iframe starts loading.
try {
await word.whenReady(); // default limit 60 s
const doc = word.getDocument(); // document handle; no round trip
const body = await doc.getBody();
const text = await body.getText();
console.log("Document text:", text);
} catch (error) {
console.error("Editor SDK request failed", error.code, error.message);
}
Expected result: the console prints text from the Word document. A timeout indicates that the editor is not ready, the origin is wrong, or the editor build does not expose the requested SDK command.
Document methods live on the document handle, not on the app handle. getDocument() returns that handle without a
round trip, so hold it in a variable and call getBody() and the other document methods on it.
4. Disconnect
window.addEventListener("pagehide", () => word.disconnect());
disconnect() is idempotent. It removes the message listener and rejects pending requests with the DESTROYED error.
The editor and the document are not affected. Calling Office.word(iframe) again returns a new handle. Disconnect
before you change the iframe src to another document or module.
After this flow works, use the Word, Spreadsheet, Presentation API references to confirm exact methods, parameters, and return types.
Try the modules
The examples below use the HTML, import map, and server setup above. Choose one example for the module script and load the matching document type in the iframe. The Word and Presentation examples modify the document; use a sample or copy.
Word
import { Office, Word } from "@thinkfree.dev/tfo-sdk";
const iframe = document.querySelector("#office-frame");
const word = Office.word(iframe);
await word.whenReady();
const doc = word.getDocument();
const body = await doc.getBody();
const para = await body.insertParagraph("Hello from tfo-sdk");
await para.setStyle(Word.Style.HEADING_1);
Spreadsheet
// Navigation calls build a path; the terminal call makes the request.
import { Office } from "@thinkfree.dev/tfo-sdk";
const iframe = document.querySelector("#office-frame");
const cell = Office.cell(iframe);
await cell.whenReady();
const ws = await cell.getWorkbook().getWorksheet(0);
const values = await ws.getRange("A1:B2").getValues();
console.log("A1:B2 values:", values);
Presentation
import { Office, ShapePreset } from "@thinkfree.dev/tfo-sdk";
const iframe = document.querySelector("#office-frame");
const show = Office.show(iframe);
await show.whenReady();
const slides = await show.getDocument().getSlides();
if (slides.length === 0) throw new Error("Open a presentation with at least one slide.");
const shape = await slides[0].insertShape(ShapePreset.RECT);
One iframe is bound to one module. To open a Spreadsheet or Presentation, load the matching open URL in the iframe (or
another iframe) and use Office.cell or Office.show for it.
Troubleshooting
| Symptom | Check and recovery |
|---|---|
INVALID_ARGUMENT | Check the iframe element and document type. Call disconnect() before reconnecting an iframe that was bound to a different module. |
TIMEOUT | Check for an open error inside the iframe first. Once the document appears, verify the exact origin and Office/SDK version combination before retrying. |
FRAMEWORK_ERROR | error.data.error.code returned by the editor operation |
| No message is accepted | Host and iframe origins must match the configured integration |
Continue with the module guides - Word API, Spreadsheet API, Presentation API - or read Architecture and lifecycle before adding the SDK to a production application.