fix(web): fix japanese text in file viewer not rendering#29051

merged3
main
GitHub fork: fix/docx-cjk-fonts
opened9d agobyNNatur7a
View on GitHubTwo-way sync enabledPR last imported 2h ago

Problem

Japanese text in a .docx opened in the file viewer renders as empty boxes, while Latin text and digits render normally. Changing the document font from Yu Gothic to MS Gothic does not help. The same file opens correctly in Microsoft Word. PowerPoint files with Japanese, Chinese or Korean text have the same problem.

Reproduce on Windows 11 with the desktop app. Create a .docx with a Japanese table in Yu Gothic or MS Gothic, then open it from a link in a thread. Expected: the Japanese text renders.

Change

The Word and PowerPoint viewers draw text only with the font files the app gives them, never with system fonts. The app aliased the @betteroffice/fonts-cjk add-on to an empty stub to keep about 33 MB of fonts out of the build. As a result, every Japanese, Chinese and Korean family fell back to a Latin face with no CJK glyphs.

This PR adds @betteroffice/fonts-cjk@0.4.0 and deletes the stub, its Vite alias, and the filtering in office/fonts.ts that skipped the missing faces. slide-fonts.ts now calls resolveScriptFallbackFace directly. It also adds the Noto CJK license notice to third-party-licenses.config.json.

The faces still load from the app's own files, so no font request leaves the machine. The production build emits them as separate assets. Only the Word and PowerPoint workers reference them, through a 580-byte chunk, so startup and documents without CJK text are unchanged. A Japanese document fetches one 4.5 MB face (3.9 MB gzipped) once, and the browser cache serves it after that. The cost is about 35 MB of extra assets in the desktop app and the npx t3 package. Spreadsheets already draw with system fonts and needed no change.

Scope and approval

Fixes issue #28990 . Related to #22039, which was closed as a duplicate.

The change is limited to the Office viewer's font loading. It ships the font package the viewer's font code was written to use, adds no setting, and makes no other behavior change.

Verification

I rendered a Japanese table document in Yu Gothic through the real WordDocument viewer and Word engine in Chromium, once before the fix and once after. Only the code differed between the runs, with the add-on installed both times. Before, every Japanese character is a box while "SES", "SMTP" and digits render. After, all the text renders.

Before:

After:

apps/web/src/components/files/office/fonts.browser.test.ts checks that Yu Gothic, MS Gothic and the Japanese script fallback load Noto Sans JP. It failed 3 of 3 before the fix (expected undefined to be 4533028) and passes 3 of 3 after.

vp build emits the five CJK faces as separate assets. The web typecheck (tsc --noEmit), vp fmt and vp lint pass on the changed files, and knip passes. I committed with --no-verify because the pre-commit hook's lint step hung on Windows without starting. Running that same lint command directly on the staged files passed.

Not checked: a Japanese PowerPoint file at runtime (same code path, untested), and the packaged desktop app (same Chromium rendering path as the test above).

Claude Opus 5.5, Claude Code in T3 Code.

Fixes pingdotgg/t3code#28990

Checks

23 successful · 14 skipped
All checks passed
8eceacb

Added 1 commit

  • fix(client): fix japanese text in file viewer not rendering3bcb0dc
Synced from GitHub

Approvability

Verdict: Approved at 3bcb0dc

Macroscope's review found this PR approvable — Restores Japanese, Chinese and Korean text rendering in Word and PowerPoint previews using bundled fonts. The impact is limited to viewer font loading and increased package size, without changing stored documents or introducing external font services.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The web app now uses @betteroffice/fonts-cjk instead of a local empty alias. Word and presentation font selection pass resolved faces through without CJK filtering. Slide fallback uses the package resolver, and browser tests check Japanese font byte lengths.

Changes: CJK font loading

Layer / File(s)Summary
Add the CJK font package
apps/web/package.json, apps/web/src/components/files/office/fonts-cjk.ts, apps/web/vite.config.ts, third-party-licenses.config.json
The web app adds @betteroffice/fonts-cjk version 0.4.0, removes the local empty font module and its Vite alias, and adds package license metadata.
Resolve CJK faces in office documents
apps/web/src/components/files/office/fonts.ts, apps/web/src/components/files/office/slide-fonts.ts, apps/web/src/components/files/office/fonts.browser.test.ts
Word and presentation font selection no longer filters out CJK faces or uses the removed retry helpers. Slide fallback uses resolveScriptFallbackFace. Browser tests compare Japanese font byte lengths with the bundled Noto Sans JP font.

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

  • pingdotgg/t3code, issue 28990: It concerns Japanese glyphs rendering as boxes in the Word viewer, which aligns with this change’s CJK font package and fallback updates.

Suggested reviewers: maria-rcks

Merge Risk: External image Minimal · up to 3bcb0

The change enables bundled CJK fonts for Word and PowerPoint. No merge-blocking risk was identified.

Pre-merge checks: Passed 4

Check nameStatusExplanation
Title checkPassedThe title is concise, uses the required conventional commit format, and clearly identifies the web file viewer fix for Japanese text rendering.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Description checkPassedThe description covers the problem, change, scope and approval context, and verification. It reports test results, includes before-and-after screenshots, and identifies checks that were not completed.
Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info

External image Run configuration

External image Commits

Reviewing files that changed from the base of the PR and between d890e5c40120769badcf18bff6d1ac983c8f40c7 and 3bcb0dca099a013b5d9dcd62b402c9f1d1b7b980.

External image Files ignored due to path filters: 1

  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
External image Files selected for processing: 7

  • apps/web/package.json
  • apps/web/src/components/files/office/fonts-cjk.ts
  • apps/web/src/components/files/office/fonts.browser.test.ts
  • apps/web/src/components/files/office/fonts.ts
  • apps/web/src/components/files/office/slide-fonts.ts
  • apps/web/vite.config.ts
  • third-party-licenses.config.json
External image Files with no reviewable changes: 2

  • apps/web/src/components/files/office/fonts-cjk.ts
  • apps/web/vite.config.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

verified 3bcb0dca099a013b5d9dcd62b402c9f1d1b7b980 against github/main at cbd3e149a1 in this linux boat vm. ran one background dev server at a time, with isolated state, playwright from the repo, and /usr/bin/google-chrome.

created a real git project through the app. a real codex gpt-6.1-sol turn generated the office documents and thread links. opened those links in the app's file viewer. reused identical document bytes for both runs. a second real codex turn completed on the pr server and returned fresh links.

  • main: yu gothic and ms gothic word tables showed cjk boxes while latin labels and digits rendered. the pr renders japanese, chinese, and korean correctly.
  • powerpoint: the pr fixes korean boxes seen on main. japanese and chinese still render. the calibri japanese slide, bold/italic text, and next/previous navigation work.
  • latin-only word text, bold/italic formatting, and closing/reopening previews work.
  • captured local requests for the japanese, chinese, and korean noto font assets.
  • blacksmith: the existing font browser test passed all 3 cases after installing chromium on the worker. existing ci checks are green. no code changes were needed.

word before:

main word viewer showing cjk boxes

word after:

pr word viewer rendering japanese chinese and korean

powerpoint before:

main powerpoint viewer showing missing korean glyphs

powerpoint after:

pr powerpoint viewer rendering all three scripts

fresh-link opening, reopening, and slide navigation:

real app office preview interaction recording

command and runtime transcript

Not verified

the original windows 11 desktop case, packaged desktop builds, macos, native ios/android, relay/tunnel connections, and production font packaging or size/performance claims were not exercised on this linux vm. japanese and chinese powerpoint already rendered on main here, so those original missing-glyph cases were not reproduced for powerpoint.

Synced from GitHub

Note

Claude Opus 5.5 responding on behalf of Natur7a

Thanks for the real-app run, the before and after screenshots, and the transcript.

The Word result matches the screenshots. On main, the Yu Gothic and MS Gothic tables show boxes for Japanese, Chinese, and Korean. This branch renders all three. I also reproduced this on Windows 11. On main, a Yu Gothic table shows boxes for every Japanese, Chinese, and Korean character while SES, SMTP, and the digits render. On this branch, the Yu Gothic and MS Gothic documents render all three scripts.

Windows 11, main, Word:

Windows 11, this branch, Word:

The PowerPoint result differs from the PR description. On this Linux VM, main already renders the Japanese and Chinese slides, and only Korean fails. On Windows 11, main renders the Japanese, Chinese, and Korean slides without boxes, so I could not reproduce a PowerPoint failure there. The description says all three scripts fail in PowerPoint. I will narrow that claim to match what we can reproduce.

Windows 11, main, PowerPoint:

Windows 11, this branch, PowerPoint:

The before run used cbd3e149a1, but the PR is based on e6e2ab05c. The 51 commits between them do not touch the office viewer, the font code, the license config, or the Vite config. They also leave the @betteroffice packages unchanged, so the comparison still isolates this change.

One correction to the description. fonts.browser.test.ts is new in this PR, so it is not an existing test. It fails 3 of 3 before the fix and passes 3 of 3 after.

Still not verified: packaged desktop builds, macOS, and native mobile.

Added 2 commits

  • Merge branch 'main' into fix/docx-cjk-fontsac106a9
  • Merge branch 'main' into fix/docx-cjk-fonts8eceacb
Synced from GitHub

Thanks for the mention @juliusmarminge!

Just for context, I haven't actively maintained #29051 recently since there hadn't been any review feedback or updates on its status, and it hadn't been merged. I wasn't sure whether it was still being considered.

I'm happy to revisit it and address any feedback or required changes. Thanks for recognizing the work!