> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sublay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Languages & Right-to-Left

> Install the comment sections in another language and use them in right-to-left layouts

export const AddCommandBuilder = ({component: initialComponent = "comments-threaded"}) => {
  const components = [{
    value: "comments-threaded",
    label: "Threaded comments",
    translated: true
  }, {
    value: "comments-social",
    label: "Social comments",
    translated: true
  }, {
    value: "notifications-control",
    label: "Notifications",
    translated: false
  }];
  const languages = [{
    value: "en",
    label: "English"
  }, {
    value: "ar",
    label: "Arabic — العربية"
  }, {
    value: "zh",
    label: "Chinese (Simplified) — 简体中文"
  }, {
    value: "nl",
    label: "Dutch — Nederlands"
  }, {
    value: "fr",
    label: "French — Français"
  }, {
    value: "de",
    label: "German — Deutsch"
  }, {
    value: "he",
    label: "Hebrew — עברית"
  }, {
    value: "hi",
    label: "Hindi — हिन्दी"
  }, {
    value: "id",
    label: "Indonesian — Bahasa Indonesia"
  }, {
    value: "it",
    label: "Italian — Italiano"
  }, {
    value: "ja",
    label: "Japanese — 日本語"
  }, {
    value: "ko",
    label: "Korean — 한국어"
  }, {
    value: "pl",
    label: "Polish — Polski"
  }, {
    value: "pt",
    label: "Portuguese — Português"
  }, {
    value: "ru",
    label: "Russian — Русский"
  }, {
    value: "es",
    label: "Spanish — Español"
  }, {
    value: "tr",
    label: "Turkish — Türkçe"
  }];
  const [component, setComponent] = useState(initialComponent);
  const [language, setLanguage] = useState("en");
  const [copied, setCopied] = useState(false);
  const translated = components.find(c => c.value === component)?.translated;
  const lang = translated ? language : "en";
  const command = `npx @sublay/cli add ${component} --ref v8${lang === "en" ? "" : ` --lang ${lang}`}`;
  const copy = () => {
    navigator.clipboard?.writeText(command).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    });
  };
  const fieldClass = "mt-1 w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100";
  const labelClass = "text-sm font-medium text-zinc-700 dark:text-zinc-300";
  return <div className="not-prose my-6 rounded-xl border border-zinc-200 p-4 dark:border-zinc-800">
      <div className="grid gap-4 sm:grid-cols-2">
        <label className={labelClass}>
          Component
          <select className={fieldClass} value={component} onChange={e => setComponent(e.target.value)}>
            {components.map(c => <option key={c.value} value={c.value}>
                {c.label}
              </option>)}
          </select>
        </label>
        <label className={labelClass}>
          Language
          <select className={fieldClass} value={lang} disabled={!translated} onChange={e => setLanguage(e.target.value)}>
            {languages.map(l => <option key={l.value} value={l.value}>
                {l.label}
              </option>)}
          </select>
        </label>
      </div>

      <div className="mt-4 flex items-center gap-3 rounded-lg bg-zinc-950 px-4 py-3">
        {}
        <span dir="ltr" className="min-w-0 flex-1 break-words font-mono text-sm text-zinc-100">
          {command}
        </span>
        <button type="button" onClick={copy} className="shrink-0 rounded-md border border-zinc-700 px-3 py-1 text-xs font-medium text-zinc-200 hover:bg-zinc-800">
          {copied ? "Copied" : "Copy"}
        </button>
      </div>

      <p className="mt-3 text-xs text-zinc-500 dark:text-zinc-400">
        The platform (React, React Native or Expo) and the style (styled or
        Tailwind) come from your <code>sublay.json</code>, written by{" "}
        <code>npx @sublay/cli init</code>.
      </p>
    </div>;
};

# Languages & Right-to-Left

The comment sections keep all their text in one file, and their layout follows the reading direction of your app. Both apply to the social and threaded comments, in every style variant, on React, React Native and Expo.

***

## Installing in another language

Pass `--lang` to `add`. Pick a component and a language to get the command:

<AddCommandBuilder />

| Code | Language |
| - | - |
| *(none)* | English |
| `ar` | Arabic |
| `de` | German |
| `es` | Spanish |
| `fr` | French |
| `he` | Hebrew |
| `hi` | Hindi |
| `id` | Indonesian |
| `it` | Italian |
| `ja` | Japanese |
| `ko` | Korean |
| `nl` | Dutch |
| `pl` | Polish |
| `pt` | Portuguese |
| `ru` | Russian |
| `tr` | Turkish |
| `zh` | Chinese (Simplified) |

The component is the same in every language. `--lang` only decides which text goes into its strings file. If the component has no translation for the code you pass, `add` lists the languages it has and installs nothing.

***

## The strings file

Every piece of text the section shows is in `utils/strings.ts` inside the component's folder: placeholders, button labels, tooltips, the report dialog, error messages and relative times. Nothing else in the component contains user-facing text, so rewording or translating it is an edit to this one file.

```ts theme={null}
// utils/strings.ts
const strings = {
  commentPlaceholder: "Join the conversation",
  reply: "Reply",
  replyCount: (count: number) => `${count} ${count === 1 ? "reply" : "replies"}`,
  // ...
};

export default strings;
```

Entries that depend on a number or a name are functions, so a language can use its own plural forms and word order. Hebrew, for example, has its own form for two, and the Russian, Polish and Arabic files carry a small helper for their several plural forms:

```ts theme={null}
replyCount: (count: number) =>
  count === 1 ? "תגובה אחת" : count === 2 ? "שתי תגובות" : `${count} תגובות`,
```

The social comments show relative times ("5 minutes ago"). Their wording is in the same file, under `timeAgo`, with one function per unit.

To translate into a language that is not in the table above, install the component in English and replace the values in `utils/strings.ts`.

The label on the GIF button stays "GIF" in every language and is not in the strings file.

***

## Right-to-left layouts

The sections lay themselves out from the start of the line to its end instead of from left to right, so they mirror in a right-to-left app with no setup: avatars, indentation, the thread lines and their elbows, the highlight strip of a highlighted comment, the reply bar, menus and the GIF picker.

**React (Web)** — the section follows the `dir` of the page, or of any element around it:

```tsx theme={null}
<div dir="rtl">
  <ThreadedCommentSection foreignId="article-123" />
</div>
```

**React Native / Expo** — the section follows the layout direction of the app, which React Native takes from `I18nManager`.

Arabic and Hebrew are right-to-left languages.

Direction and language are independent. A right-to-left app gets a right-to-left section whatever language its strings are in, and installing with `--lang he` does not change the direction of your app.

### Text written by users

On React, a comment is laid out in the direction of its own text, so an English comment in a right-to-left section reads left to right and a Hebrew comment in a left-to-right section reads right to left. The same goes for the text in the input while it is being typed; while the input is empty, its placeholder follows the page.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.