Right-to-left text

Edit Arabic, Hebrew, Persian, and Urdu documents. Set paragraph direction with the toolbar, keyboard, or code.

You can open and edit Arabic, Hebrew, Persian, and Urdu documents with right-to-left (RTL) or mixed-direction text. Change paragraph direction through the toolbar, keyboard, or browser Editor API.

How the editor reads direction

A DOCX file stores direction at two levels. The editor reads both levels:

PropertyScopeEffect
w:bidiParagraphSets the base direction for lines, list markers, and indents.
w:rtlRunOrders numbers and punctuation right to left, and selects the run's complex-script formatting.

Alignment and indents name the leading and trailing sides of a paragraph. In an RTL paragraph, w:jc="left" aligns to the right margin. The w:ind w:left property indents from the right. First-line and hanging indents count from the right indent. The kashida justification values justify the paragraph.

List levels follow the same rule. In an RTL paragraph, a level's w:ind w:left indents from the right margin. The w:lvlJc="left" property aligns the marker's right edge with its position. The marker text reads right to left. For example, 1. shows its period on the left. The hebrew1, hebrew2, arabicAlpha, arabicAbjad, and hindiNumbers formats number in their own scripts.

Tab stops count from the right margin, and the text on each side of a tab stays in reading order.

The ruler mirrors for an RTL paragraph. The first-line, hanging, and Before text handles appear on the right. The After text handle appears on the left. The Paragraph dialog's Before text and After text fields edit w:ind w:left and w:ind w:right.

Complex-script formatting

A run with w:rtl or w:cs uses complex-script properties for every character. This includes digits and Latin letters:

  • w:rFonts w:cs or w:cstheme selects the font. With neither, the run uses Times New Roman.
  • w:szCs sets the size. With no w:szCs, the run is 10 pt.
  • w:bCs and w:iCs set bold and italic.

w:sz, w:b, and w:i have no effect on such a run. A run without w:rtl or w:cs uses the Latin properties, even for Arabic or Hebrew characters.

Formatting commands use the effective w:rtl and w:cs values, including character styles, paragraph styles, table styles, and document defaults. Direct false values override inherited values. For complex-script runs, commands write both property variants. For example, Bold writes <w:b/><w:bCs/>. It writes <w:b/> on a left-to-right (LTR) run. Selection formatting, caret typing, paragraph marks, format painter, and automation font writes follow this rule.

Change paragraph direction

You can change the direction of the paragraphs in the selection in four ways:

  • Toolbar: the Left-to-right text and Right-to-left text buttons follow the alignment control. A mixed selection shows neither button as pressed.
  • Format menu: the same two commands follow the alignment rows.
  • Paragraph dialog: the Direction setting.
  • Keyboard: press Ctrl+Right Shift for RTL and Ctrl+Left Shift for LTR. The command runs when you release the keys. If you press another key or click before you release them, the command does not run. On macOS, use the Control key.

The shortcuts require an RTL paragraph or run in the document region you edit. This requirement avoids overriding Ctrl+Shift keyboard-layout switching in other documents.

The command changes only the paragraph direction. It does not change the text, the run direction, or w:jc. A paragraph aligned to its start moves to the other margin. Paragraphs in table cells change too.

Change direction from code

Use the browser Editor API's setParagraphDirection command. It applies to every paragraph that the selection touches. The command creates one undo step.

import type { Editor } from '@docx-editor.dev/core';

function makeRightToLeft(editor: Editor) {
  const command = { type: 'setParagraphDirection', direction: 'rtl' } as const;
  const permission = editor.can(command);
  return permission.ok ? editor.exec(command) : permission;
}

The command writes these values:

RequestParagraph already in that directionOtherwise
'rtl'No change<w:bidi/>
'ltr'No changeRemoves the paragraph's own w:bidi. If a style sets RTL direction, writes <w:bidi w:val="0"/> instead.

Protected and read-only documents refuse the command, like other paragraph formatting. The setParagraphFormat command also accepts direction.

To read the direction at the selection, use the formatting snapshot. When selected paragraphs disagree, the snapshot omits direction and sets disagrees.direction to true.

const formatting = editor.snapshot().formatting;
const direction = formatting?.direction ?? (formatting?.disagrees?.direction ? 'mixed' : 'ltr');

To build your own buttons, use the direction.ltr and direction.rtl chrome slots.

Export RTL text to PDF

PDF export preserves Arabic joining across formatting runs and uses fonts that support Arabic shaping. The PDF text layer keeps Arabic, Persian, and Hebrew words in logical order for text extraction. Default fallback fonts cover Arabic and Hebrew when the selected font lacks those characters.

For font configuration, see Configure PDF fonts. For supported content, see Word feature support.

Limits

  • The editor does not add w:rtl to typed text. Text that you type in an RTL run keeps that run's direction.
  • Section direction (w:sectPr/w:bidi) and run direction wrappers (w:dir, w:bdo) do not change layout.
  • The editor interface does not mirror for RTL languages.