Text direction extension for Tiptap
npm install tiptap-text-directionThis extension automatically detects text direction (LTR / RTL) for configurable Tiptap node types and applies the appropriate dir="ltr" or dir="rtl" attribute.
It is useful when working with mixed-direction content (e.g. English + Arabic/Persian/Hebrew) and when you need explicit, overridable direction control at the node level.
It is compatible with Tiptap v2 and v3.
> [!NOTE]
>
> Differences with the built-in feature
>
> TipTap has recently added built-in support for RTL text.
> However, this feature relies on using dir="auto" for automatic direction detection.
>
> In contrast, this extension detects the language using JavaScript and explicitly sets the direction to either dir="ltr" or dir="rtl".
>
> This approach has two main advantages:
>
> 1. It provides clearer information about the actual direction of the text nodes, especially when saving documents on the server.
> The dir="auto" option can be ambiguous and depends on the browser's interpretation.
> 2. It allows for more granular control when applying styles.
> For instance, you can target elements based on their text direction, which is not possible with dir="auto".
>
> That said, the built-in feature is a perfectly acceptable option if you don't need these specific functionalities.
``bashpnpm
pnpm install tiptap-text-direction
Usage
Below is a React example, but the extension works with any framework supported by Tiptap.
`tsx
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import TextDirection from "tiptap-text-direction";const Tiptap = () => {
const editor = useEditor({
extensions: [
StarterKit,
TextDirection.configure({
types: ["heading", "paragraph"],
}),
],
});
return ;
};
`Styling based on direction
Since direction is explicitly set, you can easily style content using attribute selectors:
`css
.ProseMirror p[dir="rtl"],
.ProseMirror h1[dir="rtl"],
.ProseMirror h2[dir="rtl"],
.ProseMirror h3[dir="rtl"],
.ProseMirror h4[dir="rtl"],
.ProseMirror h5[dir="rtl"],
.ProseMirror h6[dir="rtl"] {
text-align: right;
}.ProseMirror p[dir="ltr"],
.ProseMirror h1[dir="ltr"],
.ProseMirror h2[dir="ltr"],
.ProseMirror h3[dir="ltr"],
.ProseMirror h4[dir="ltr"],
.ProseMirror h5[dir="ltr"],
.ProseMirror h6[dir="ltr"] {
text-align: left;
}
`Options
$3
A list of node types that should receive the
dir attribute.Default:
[]`ts
TextDirection.configure({
types: ["heading", "paragraph"],
});
`$3
If the editor is inside a parent element with a known direction (commonly
or ), you can set defaultDirection to avoid adding redundant dir attributes.This helps keep the generated HTML smaller and cleaner.
Default:
null`ts
TextDirection.configure({
defaultDirection: "rtl",
});
`Commands
$3
Explicitly set the text direction of matching nodes within a range or the current selection.
`ts
// Apply to the current selection
editor.commands.setTextDirection("rtl");// Apply to a specific range
editor.commands.setTextDirection("ltr", { from: 0, to: 10 });
// Apply at a specific document position
editor.commands.setTextDirection("rtl", 42);
`$3
Remove the explicit text direction attribute from matching nodes and revert back to
defaultDirection.`ts
// Remove from the current selection
editor.commands.unsetTextDirection();// Remove from a specific range
editor.commands.unsetTextDirection({ from: 0, to: 10 });
// Remove at a specific document position
editor.commands.unsetTextDirection(42);
`Keyboard shortcuts
| Command | Windows/Linux | macOS |
| ----------------------- | -------------------- | ------------------- |
| setTextDirection("ltr") |
Ctrl + Alt + l | Cmd + Alt + l |
| setTextDirection("rtl") | Ctrl + Alt + r | Cmd + Alt + r |Notes
- Direction detection is based on content-based, but the resulting
dir` value is explicit and stable.