# Languages and RTL (https://docs.salla.dev/twilight/react/guide/languages-and-rtl)



Read this when you add text to your theme, or support both Arabic and English.

Salla stores are multilingual, and Arabic is right-to-left (RTL). The engine handles language and direction for you.
Your job is to put text in translation files and write layout that works both ways.

## The language comes from the URL [#the-language-comes-from-the-url]

Every route starts with the optional `{-$locale}` segment (see [Routes and pages](https://docs.salla.dev/twilight/react/guide/routes-and-pages)).
For `/en/cart`, the locale is `en`. On a store with several languages, a URL without the segment redirects to `/ar/...`.
From the locale it also picks the direction: `ar`, `fa`, `he` and `ur` are RTL, everything else is LTR.

The root route writes both onto the page, so the first server render already has the right direction:

```tsx title="app/routes/__root.tsx"
import { getTwilightContext } from '@salla.sa/twilight-theme-engine/tanstack';

function RootComponent() {
  const ctx = getTwilightContext();

  return (
    <html lang={ctx.locale} dir={ctx.dir} suppressHydrationWarning>
      {/* … */}
    </html>
  );
}
```

## Translation files [#translation-files]

Your theme's strings live in `locales/ar.json` and `locales/en.json`. Keys are **flat strings with dots**, not nested objects:

```json title="locales/en.json"
{
  "pages.cart.total": "Total",
  "pages.cart.empty_cart": "Your cart is empty",
  "pages.products.add_to_cart": "Add to Cart",
  "common.actions.save": "Save"
}
```

`vite.config.ts` points the plugin at the folder (`twilightReact({ localesDir: './locales' })`), and the root route hands
the result to the provider:

```tsx title="app/routes/__root.tsx"
import themeTranslations from 'virtual:twilight/theme-translations';

<TwilightProvider translations={themeTranslations} layout={ThemeLayout}>
  <Outlet />
</TwilightProvider>
```

Without that `translations` prop none of your files load. Add every key to every language file.
The [translation keys recipe](https://docs.salla.dev/twilight/react/recipes/add-translation-keys) covers the steps.

<Callout>
  The store's own translations from Salla are looked up first, and your theme files are the fallback.
  If a key you added seems ignored, the same key probably exists on the Salla side.
</Callout>

## Use a translation [#use-a-translation]

`useTranslation` returns `t` plus the language facts:

```tsx
import { useTranslation } from '@salla.sa/twilight-theme-engine/i18n';

function AddToCart() {
  const { t, locale, isRTL } = useTranslation();
  return <button>{t('pages.products.add_to_cart', 'Add to Cart')}</button>;
}
```

The second argument is the fallback text, shown when the key is missing, so customers never see a raw key.
Besides `t`, you get `locale`, `direction`, `isRTL`, `isLTR` and `languageName`.
`t` behaves as in react-i18next, and works during server rendering in the language of the request.
Outside the provider the language fields fall back to Arabic, right to left.
Every field and the full signature are on the [useTranslation page](https://docs.salla.dev/twilight/react/hooks/use-translation).

### Placeholders [#placeholders]

Put values in the string with `{{name}}` and pass them as options. Use `defaultValue` for the fallback in this form:

```tsx
t('store.closed_notification', { defaultValue: 'Closed until {{nextOpen}}', nextOpen })
```

### Plurals [#plurals]

Some Salla strings use Laravel-style plural segments such as `{1} once|[3,10] :count times`.
Plain `t()` cannot read those, so run the result through `formatSallaPlural`:

```tsx title="app/components/product/ProductDetails.tsx"
import { formatSallaPlural } from '@salla.sa/twilight-theme-engine/utils';

<span>{formatSallaPlural(t('pages.products.sold_times'), product.sold_quantity ?? 0)}</span>
```

It picks the matching segment, fills in `:count`, and strips inline tags.

## Write layout that works both ways [#write-layout-that-works-both-ways]

Use logical classes so one design serves both directions:

| Use                               | Instead of                |
| --------------------------------- | ------------------------- |
| `ms-4`, `me-4`                    | `ml-4`, `mr-4`            |
| `ps-4`, `pe-4`                    | `pl-4`, `pr-4`            |
| `text-start`, `text-end`          | `text-left`, `text-right` |
| `rtl:rotate-180` on an arrow icon | two icons behind an `if`  |

Arrows and chevrons are the usual RTL bug. Open your page at `/ar` and `/en` side by side before you call it done.

**Next:** [Settings](https://docs.salla.dev/twilight/react/guide/settings), to let merchants configure your theme.
