Uh oh!
There was an error while loading. Please reload this page.
fix(app): correct RTL rendering for mixed Arabic/English content - #37249
fix(app): correct RTL rendering for mixed Arabic/English content#37249ahmed7542 wants to merge 1 commit into
Conversation
Mixed RTL/LTR text in the chat composer and rendered markdown was displayed in the wrong order, with paragraphs aligned to the left edge of their container regardless of the dominant script. - Add session-ui/components/rtl.ts: a small helper that detects the base direction of a string from its first strong character and walks a block tree to set dir="auto" on the nearest block ancestor. - Wire the helper into the markdown component so dir="auto" is set on paragraphs, list items, and table elements each time a block is rendered or updated. - Set dir="auto" on the prompt input's contenteditable elements so the editor and rendered text share a base direction. - Add scoped CSS rules: unicode-bidi: plaintext on text containers inside [data-component="markdown"], explicit dir on tables for column order, and direction: ltr on pre/code to keep code blocks unchanged. Fixes the rendering portion of anomalyco#35319. The CSS in the issue's recipe is applied via the global stylesheet rather than at the webContents level so the change is part of the regular build and the desktop/web builds stay in sync.
The following comment was made by an LLM, it may be inaccurate: Potential Duplicate Found:
This PR appears to address the same issue (RTL text direction detection for mixed Arabic/English content). Since your PR #37249 is described as "the native implementation of the recipe discussed in #35319" and closes issues #32726 and #32984, it may supersede or be related to PR #32727. You should verify whether #32727 is still open and if there's any overlap in scope or implementation. |
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
Ham3dParsa
commented
Jul 22, 2026
Also opened PR #38318 which addresses the same issue from the Electron desktop preload layer (DOM injection + MutationObserver). It's complementary — yours handles the component layer (session-ui/app), mine handles the Electron renderer. Both together cover all cases. |
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Fixes#35319
Type of change
What does this PR do?
Mixed RTL/LTR text in the chat composer and rendered markdown was displayed in the wrong visual order, with paragraphs and tables left-aligned regardless of the dominant script. For users of Arabic, Hebrew, Persian, and Urdu, this made the chat experience unusable.
Root cause: text nodes inside the markdown container have no
dirattribute and nounicode-bidideclaration, so they inherit the document's LTR base direction. The CSS in #35319's recipe (inserted viawebContents.insertCSS) was the working workaround, but applying it through the build is the right long-term fix.Changes:
packages/session-ui/src/components/rtl.ts(new): two helpers that detect base direction from the first strong character of a string and walk a block tree to setdir="auto"on the nearest block ancestor. A second helper flips the explicitdiron<table>elements so column order matches the dominant script.packages/session-ui/src/components/markdown.tsx: invoke the helpers each time a block is rendered or updated, afterinnerHTMLis set and beforedecorateruns.packages/app/src/components/prompt-input.tsx: adddir="auto"to the twocontenteditablecomposer elements so the editor and the rendered text share a base direction.packages/app/src/index.css: scoped rules under[data-component="markdown"]—unicode-bidi: plaintexton text containers,margin-left: autofortable[dir="rtl"], anddirection: ltr+unicode-bidi: isolateonpre/codeso code blocks stay unchanged.Why
unicode-bidi: plaintextand notdirection: rtl: the original issue's recipe (and our testing) shows that settingdirection: rtlon free-flowing mixed Arabic/English text re-scrambles the bidi runs of inline English words.plaintextcorrectly orders each run by the script of the first strong character, which is what WhatsApp/Telegram/Slack do.How did you verify your code works?
I built the web app locally against the OpenCode backend (
bun --cwd packages/app dev -- --port 4444+bun run --cwd packages/opencode serve --port 4096) and verified:The visual test plan in the original issue (#35319) maps 1:1 to the four changes above.
Screenshots / recordings
I have not captured screenshots, but the workaround screenshots in #35319 (the
before-rtl-*andafter-rtl-*attachments) show the exact behaviour this PR restores. Reviewers can runbun --cwd packages/app dev -- --port 4444and type a mixed Arabic/English message to reproduce the fixed output locally.Checklist