Skip to content

[codex] Add SEO landing pages#91

Draft
chaxus wants to merge 32 commits into
mainfrom
upgrade/onlyoffice-9.3.0
Draft

[codex] Add SEO landing pages#91
chaxus wants to merge 32 commits into
mainfrom
upgrade/onlyoffice-9.3.0

Conversation

@chaxus

@chaxus chaxus commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Reposition the homepage from a DOCX-only editor to a local/private multi-format document editor.
  • Add SEO landing pages for DOCX, XLSX, PPTX, CSV, private document editing, OnlyOffice WASM, embedding, and self-hosted deployment.
  • Add robots/sitemap entries, Vite multi-page build inputs, landing-page UI content, and a unit test that guards the SEO page matrix.

Validation

  • pnpm test — 7 files, 96 tests passed
  • pnpm run lint:ts — passed
  • pnpm run format:check — passed
  • pnpm run build — passed
  • pnpm run test:e2e — 10 passed

Notes

The branch also contains the existing OnlyOffice 9.3.0 upgrade commits that were already on upgrade/onlyoffice-9.3.0 before this SEO commit.

chaxus and others added 30 commits May 31, 2026 11:58
- sdkjs: 7.5.0 → 9.3.0 (word/cell/slide/common; removed pdf/visio)
- web-apps: 7.5.0 → 9.3.0 (doc/spreadsheet/presentation editors only;
  removed mobile/embed/forms/pdfeditor/visioeditor/help/ie/.gz)
- x2t WASM: 7.5.0 → 9.3.0+0 (cryptpad build; 55MB → 34MB)

Key gains: v9.2 Plugin API expansion (needed for Agent dev),
v9.3 PDF API, image/shape hyperlinks, REGEX functions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docs/explorations/: new directory for tracking change explorations
- 2026-05-31-onlyoffice-9.3.0-upgrade.md: full process log covering
  Docker extraction, x2t WASM upgrade, URL fix, version-hash rewrite,
  and root cause (Document Server vs Desktop Editors build difference)
- lib/document-converter.ts: use absolute URL when loading x2t.js
- vite.config.ts: Vite plugin to strip OnlyOffice version-hash prefix
  and return 404 for socket.io polling paths during dev

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New: 2026-05-31-onlyoffice-desktop-mode-mock.md
  - Two initialization paths: Server vs Desktop mode
  - AscDesktopEditor mock method list with root cause for each
  - GetInstallPlugins must return 2 groups (SDK accesses a[0].url/a[1].url)
  - LocalStartOpen fires per font script — need guard
  - Common.Gateway event system internals (jQuery-wrapped, no external trigger)
  - asc_openDocumentFromBytes confirmed working via DevTools
  - Emscripten WASM heap copy pitfall
  - api.js patches: ver='', parentOrigin='file://'
  - AllFonts.js missing from Desktop sdkjs — copy from Docker backup
  - Remaining: appReady intercept timing for binary injection
- Update: upgrade doc status to reflect current progress

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… loading

The key discoveries that make this work:
- 9.3.0 Shc() is overridden in Desktop mode to call LocalStartOpen instead
  of processing binary data; clearing AscDesktopEditor temporarily makes
  it use the original BRj() path that processes the binary directly
- Binary must be injected at 500ms after LocalStartOpen (font engine ready)
- AllFonts.js replaced with original 7.5.0 version (empty __fonts_files
  to avoid ascdesktop://fonts/ protocol errors)
- api.js patched: ver='' (no hash prefix) and parentOrigin="file://"
- Vite plugin injects AscDesktopEditor mock into editor index.html
- onlyoffice-editor.ts stores binary in window.__pendingBinary for iframe access

Remaining: suppress Connection is lost dialog, fix font loading via
ascdesktop:// → /fonts/ redirect.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
….warning intercept

- vite.config.ts: add Common.UI.warning intercept in mock to suppress
  the Connection is lost dialog (which fires when socket.io disconnects)
- types/editor.d.ts: add openDocument? method to DocEditor type
- Removed XMLHttpRequest intercept for ascdesktop://fonts/ (caused SDK hang)
  SDK handles CORS failures on ascdesktop:// gracefully; 404 caused hangs

Status: document loading works (~1min due to socket.io timeout).
Text renders as gray bars pending font loading resolution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The EIO4 fake handshake caused socket.io to reconnect indefinitely,
blocking asc_onCoAuthoringDisconnect from firing. 404 causes socket.io
to retry with backoff; after ~60s the SDK fires the disconnect event
and document rendering proceeds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document the full working initialization chain, all key discoveries,
current status (60s load, gray bars text), and next steps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- vite.config.ts: XHR prototype patch maps Windows font filenames to
  our open-source alternatives (Arial→LiberationSans, Times→DejaVuSans,
  CJK→NotoSans*). Unmapped fonts keep ascdesktop:// → CORS → SDK skips.
  Common.UI.warning suppression for Connection is lost dialog.
- public/sdkjs/common/AllFonts.js: restored to 7.5.0 version (with
  Windows paths) which correctly triggers LocalStartOpen via font-script
  loading chain. Our new AllFonts.js broke the initialization order.

Status: canvas renders actual content (verified via pixel sampling),
21 fonts load successfully (70MB). Gray bars = CSS skeleton overlay,
not actual rendering state. editor:onready fires, document loads.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Full record of all findings, mechanisms, pitfalls and current status:
- Complete initialization chain with step-by-step flow
- Shc() override as the core discovery (Desktop mode ignores binary data)
- All critical pitfalls with cause and solution table
- Font redirect mechanism (XHR prototype patch + 50+ mappings)
- socket.io strategy (404 not fake handshake)
- Current status: canvas renders content, 2 UI issues remain
- Verification method for confirming canvas has actual content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Key findings from today's investigation:
- asc_nativeOpenFile(N): processes OOXML (docType=2, title changes) but
  canvas stays black — SetDrawingFreeze(false) not triggered
- asc_openDocumentFromBytes(BRj path): triggers font loading (21 fonts)
  but also needs server for actual content rendering
- Wrapping api.asc_openDocumentFromBytes in CreateEditorApi to auto-clear
  AscDesktopEditor, so every call uses BRj path without manual management
- Store original file in window.__pendingOriginalFile for asc_nativeOpenFile
- editor:onready → appReady() → parent openDocument → loadBinary chain works
- asc_onDocumentContentReady intercept timing: api.ta is null at CreateEditorApi,
  must wait until LocalStartOpen when ta is initialized

Still investigating: asc_onDocumentContentReady not firing after
asc_nativeOpenFile / SetDrawingFreeze not called → canvas stays black

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add detailed analysis of why canvas stays black:
- BRj path loads fonts but needs server for document content
- asc_nativeOpenFile doesn't trigger asc_onDocumentContentReady
- SetDrawingFreeze(false) never called → rendering never starts
- Next: intercept SetDrawingFreeze and asc_onDocumentContentReady callbacks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gging

- vite.config.ts: wrap api.asc_openDocumentFromBytes in CreateEditorApi
  to auto-clear AscDesktopEditor (BRj path); add LocalFileRecents stub
  (needed by app:ready); log SetDrawingFreeze/asc_nativeOpenFile intercepts
- lib/converter.ts: store original file in window.__pendingOriginalFile
  before x2t conversion for asc_nativeOpenFile

Findings: asc_nativeOpenFile returns docType=2 but never creates WordControl.
T_f(ooxml) and wKa.wt(binary) both fail to initialize rendering pipeline.
_isDocReady guard blocks SetDrawingFreeze from running on second call.
Need to investigate wKa.wt failure mode (font context mismatch?).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- WordControl never created despite docType=2
- _isDocReady guard blocks SetDrawingFreeze on second call
- Both T_f(ooxml) and wKa.wt(binary) fail to initialize rendering
- title:button disabled:{} confirms app:ready fired but render engine unlinked
- Next: investigate wKa.wt requirements (ta.Ga initialization)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Ec.Ms (Word Control) is the key rendering gate in M_f()
- window.Asc.editor uses jre() not qYg() → Ec.Ms never set
- Document model loads correctly (aaLen=3) but render context missing
- Manual Xxh creation possible but needs more initialization
- Best next path: implement minimal socket.io server protocol

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace all ranuts.github.io URLs with bybrowser.com across 9 HTML pages, sitemap, robots.txt, and manifest.json
- Expand each page's #seo-content from 1 sentence to 300-500 words: features, how-to steps, use cases, FAQ
- Add cross-linking nav at the bottom of every sub-page (related tools + home)
- Add SoftwareApplication JSON-LD structured data to all 9 pages
- Update manifest name/description to ByBrowser branding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- zh-cn/ subdirectory: 9 Chinese pages (homepage + 8 tool pages) with
  full translated content, hreflang zh-Hans, canonical URLs
- sitemap.xml: expanded to 18 URLs with xhtml:link alternate pairs
- vite.config.ts: added 9 zh-cn build entries + injectGtag plugin
  (GA G-VQCV194W8Q injected into all HTML at build time, skipped in dev)
- lib/i18n.ts: /zh-cn/ path detection as priority-0 language signal
- lib/loading.ts: replaced spinner with staged progress bar
  (auto-advances through 4 stages; setProgress() for milestone hooks)
- lib/document.ts + events.ts: call setProgress at initX2T/handleDoc milestones
- lib/ui.ts: ad slot infrastructure — landing page ad unit between hero
  and feature cards; editor-mode bottom strip shown on editor-open
- styles/base.css: ad-unit, editor-ad-strip, loading-overlay CSS
- All EN pages: hreflang + zh-Hans alternate already committed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract GitHub/Issues/lang-switch into fixed `.landing-nav` (position:fixed, 52px, z-index 1001)
- Remove `.lang-bar` from landing-shell; no more content-dependent positioning
- Adjust `.landing-shell` padding-top to 94px (nav height + gap) so content never shifts
- Change `.landing-hero` from align-items:end to center; remove min-height:56vh
- Add all UI strings to i18n.ts; replace ternary patterns with t() calls throughout ui.ts
- Inject critical CSS via Vite plugin to eliminate FOUC on language switch
- Add GA4 (G-VQCV194W8Q) via prod-only Vite plugin; create zh-cn/ pages and sitemap hreflang

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Show current language in picker (English/中文) instead of alternate.
Extensible: adding a new locale is one option element + getLangUrl branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lib/ store/ styles/ types/ index.ts → src/*
Update all 18 HTML entry points to reference ../src/index.ts
Update tsconfig path aliases to point into src/

URL routes unchanged; HTML page dirs stay at root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All HTML entry points moved into pages/ to separate route definitions
from source code. URLs unchanged — Vite root: 'pages' serves them at
the same paths as before (/docx-editor/, /zh-cn/, etc.).

- pages/          HTML page directories (18 entries, EN + zh-cn)
- src/            TypeScript source, styles, types
- public/         Static assets
- Fix vite resolve.alias to point into src/ (missed in prior commit)
- Add server.fs.allow so Vite can resolve src/ outside root

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 7.5 build is custom-compiled (build:1), not from any installer
- Desktop Editors 9.x also uses server architecture (code.js exists)
- Architecture changed somewhere between 7.x and 8.0
- Desktop Mode Mock abandoned: Ec.Ms init path unreachable in mock env
- Document three paths forward (compile from source / socket.io server / stay on 7.5)
- Mark current sdkjs/web-apps (Docker 9.3.0) as breaking — needs rollback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All 9.x releases (Docker, macOS DMG, Linux tarball) confirmed to use
server architecture (code.js present, app.js ~2MB). No offline path exists.

Key findings:
- Linux Desktop Editors 9.3.0 tarball verified: code.js exists
- build_tools --desktop flag no longer produces offline bundle in 9.x
- Architecture changed between 7.x and 8.x (exact version TBD)
- 7.5 build:1 was hand-compiled in the old standalone era

Three paths documented: maintain 7.5 / socket.io mock server / find last offline version

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
关键发现(通过 Desktop tarball 9.3.0 二进制分析):
- code.js(1.1MB):0 socket 引用,是纯 UI 懒加载包,与服务器无关
- socket.io 协议实现在 sdk-all-min.js(sdkjs 渲染引擎)
- sdk-all-min.js 同时包含 202 个 AscDesktopEditor 引用 → Desktop 模式有完整独立路径
- Desktop 路径:nativeOpenFile → jre() → AscCommonWord.e2(ta.Ga)→ 不经过 socket.io

修正之前 Desktop Mode Mock 失败的真实原因:
- 当时使用了 Docker 服务端 sdkjs(非 Desktop 构建)
- 从未调用 asc_nativeOpenFile 传入实际文档数据
- Ec.Ms 是 PDF viewer 路径,Word 编辑器用 ta.Ga

新增路径 C(v8.1.1 最后单体包版本)和路径 D(Desktop tarball + 正确 mock)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ument API

- Remove parentOrigin: 'file://' (was for Desktop mock path, no longer needed)
- Replace openDocument() call (9.3.0+ only) with sendCommand({ command: 'asc_openDocument' })
- Remove onlyofficeDesktopMock() plugin from vite.config.ts (caused uitheme crash in 7.4.1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- v8.1.1 also requires socket.io (tested: /doc/{key}/c/?EIO=4 → 404)
- socket.io was introduced before v8.1.1, not between 8.1.1 and 8.2.0
- Update architecture timeline with 8.x section
- Mark Path C as failed with test evidence

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Adjusted body color and background gradients for better aesthetics.
- Modified button styles for r-button webcomponent to enhance usability.
- Updated landing section styles including padding, margins, and colors for better alignment and readability.
- Enhanced workbench and format styles for a more modern look.
- Refined media queries for improved mobile responsiveness.

test: refactor unit tests to align with new module paths

- Updated import paths in document-utils, embed-api, i18n, and onlyoffice-editor tests to reflect new structure.
- Ensured all tests continue to function correctly after path changes.

build: clean up vite configuration by removing unused desktop mock function

- Removed the onlyofficeDesktopMock function and related comments from vite.config.ts to streamline the configuration.
chaxus added 2 commits June 15, 2026 22:22
- Added `src/lib/app-router.ts` to manage app startup routing and document opening.
- Refactored `src/index.ts` to utilize `initAppRouter` for initializing editor session and handling URL parameters.
- Created unit tests for app router in `test/unit/app-router.test.ts` to ensure correct wiring of callbacks and document opening logic.
- Introduced `src/lib/editor-session.ts` to manage editor session state, including history handling and session restoration.
- Added tests for editor session functionality in `test/unit/editor-session.test.ts`.
- Updated UI behavior to hide ad strip when entering editor mode in `test/unit/ui.test.ts`.
- Documented implementation plans and design specifications for app router and editor session navigation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant