Translate

This plugin provides an easy way to handle localization (i18n). You can scope locales globally or per component. You can also define locales in multiple methods based on your preference.

Global Scope

If you have global messages that are shared across your app, follow these steps to define and use messages in components and composables.

Define messages in separate files per locale.

// locales/ar.json

{
  "hello": "مرحباً"
}

In your main.ts, add your global locales to the locales option.

// main.ts

import { runApp } from '@dija/tohama-spa';

export default runApp(
    {
        ...
        initialLocale: 'en',
        locales: [
            {
                code: 'en',
                direction: 'ltr',
                messages: () => import('./locales/en.json'),
            },
            {
                code: 'ar',
                direction: 'rtl',
                messages: () => import('./locales/ar.json'),
            },
        ],
        ...
    },
);

And in your component or composable, use useGlobalTranslate:

export default defineComponent({
  setup() {
    const translate = useGlobalTranslate();

    return () => (
      <TCard design="outlined" p>
        {translate.t("hello")}
      </TCard>
    );
  },
});

Local Scope

Component Structure

We recommend this structure for your component directory:

src/components/
    my-component/
        index.ts
        component.tsx
        locales/
            index.ts
            ar.json
            en.json

Define messages in separate files per locale.

// locales/ar.json

{
  "hello": "مرحباً"
}

Import locales files and export them as messages.

// locales/index.ts

import ar from "./ar.json";
import en from "./en.json";

export const messages = { ar, en };

Import messages in your component

// component.tsx

import { messages } from "./locales";

export default defineComponent({
  setup() {
    const translate = useTranslate({
      messages: messages,
    });

    return () => (
      <TCard design="outlined" p>
        {translate.t("hello")}
      </TCard>
    );
  },
});
Hello

Asynchronous Import

This will only fetch the current locale messages on-demand, recommended if you have a large number of locales or messages.

import { messages } from "./locales";

export default defineComponent({
  async setup() {
    const translate = await useAsyncTranslate({
      uid: "my-locales",
      messages: {
        ar: () => import("./locales/ar.json"),
        en: () => import("./locales/en.json"),
      },
    });

    return () => (
      <TCard design="outlined" p>
        {translate.t("hello")}
      </TCard>
    );
  },
});
Hello

Note that when using asynchronous imports, wrap your component in the Suspense component.

const ParentComponent = defineComponent({
  setup() {
    return () => (
      <Suspense>
        <MyComponent />
      </Suspense>
    );
  },
});

Locales via Records

export default defineComponent({
  setup() {
    const translate = useTranslate({
      messages: {
        ar: {
          hello: "مرحباً",
        },
        en: {
          hello: "Hello",
        },
      },
    });

    return () => (
      <TCard design="outlined" p>
        {translate.t("hello")}
      </TCard>
    );
  },
});
Hello

Helpers

Inject Message Parameters

You can add keys to your message that can be replaced by translate. Add the key and its value and it will be replaced automatically.

export default defineComponent({
  setup() {
    const translate = useTranslate({
      messages: {
        ar: {
          hello: "مرحباً، {name}",
        },
        en: {
          hello: "Hello, {name}",
        },
      },
    });

    return () => (
      <TCard design="outlined" p>
        {translate.t("hello", { name: "Khalid" })}
      </TCard>
    );
  },
});
Hello, Yahya