1.0.0 • Published 1 year ago

@vavra7/i18n v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

Simple i18n for React

Simple package for translating texts for multilingual websites built in react.

Preconditions

Set up react application

Hooks

  • useI18n()

Example of usage

Folder structure

.
├── enums
│   └── lang.enum.ts
├── index.client.tsx
├── index.server.tsx
├── lib
│   └── i18n
│       ├── index.ts
│       └── locales
│           ├── cs
│           │   ├── global.json
│           │   ├── home.json
│           │   └── index.ts
│           ├── en
│           │   ├── global.json
│           │   ├── home.json
│           │   └── index.ts
│           └── index.ts
└── root.tsx

src/enums/lang.enum.ts

export const LangEnum = {
  Cs: 'cs',
  En: 'en'
};

export type LangEnum = (typeof LangEnum)[keyof typeof LangEnum];

src/lib/i18n/locales/en/global.json

{
  "global": {
    "buttons": {
      "changeLang": "Change Language"
    }
  }
}

src/lib/i18n/locales/en/home.json

{
  "home": {
    "header": "Home"
  }
}

src/lib/i18n/locales/en/index.ts

import global from './global.json';
import home from './home.json';

export default {
  ...global,
  ...home
};

src/lib/i18n/locales/index.ts

import cs from './cs';
import en from './en';

export const locales = {
  cs,
  en
};

src/lib/i18n/index.ts

import { I18nClient } from '@vavra7/i18n';

import { LangEnum } from '../../enums/lang.enum';
import { locales } from './locales';

export class I18n {
  private client?: I18nClient;

  public getClient(): I18nClient<LangEnum> {
    if (this.client) {
      return this.client;
    } else {
      return this.initClient();
    }
  }

  private initClient(): I18nClient<LangEnum> {
    this.client = new I18nClient<LangEnum>({
      fallbackLang: LangEnum.Cs,
      locales,
      supportedLangs: Object.values(LangEnum),
      debug: process.env.NODE_ENV === 'development'
    });
    return this.client;
  }
}

export const i18n = new I18n();

src/root.tsx

import { useI18n } from '@vavra7/i18n';
import type { FC } from 'react';
import React from 'react';

import { LangEnum } from './enums/lang.enum';

const Root: FC = () => {
  const { lang, setLang, t } = useI18n();

  return (
    <>
      <h1>{t('home.header')}</h1>
      <button onClick={() => (lang === LangEnum.Cs ? setLang(LangEnum.En) : setLang(LangEnum.Cs))}>
        {t('global.buttons.changeLang')}
      </button>
    </>
  );
};

export default Root;

src/index.client.tsx

import { I18nProvider } from '@vavra7/i18n';
import React from 'react';
import { createRoot } from 'react-dom/client';

import { i18n } from './lib/i18n';
import Root from './root';

if (module?.hot) module.hot.accept();

async function main(): Promise<void> {
  const i18nClient = i18n.getClient();
  const container = document.getElementById('root-container');
  const app = (
    <I18nProvider client={i18nClient}>
      <Root />
    </I18nProvider>
  );
  createRoot(container!).render(app);
}

main();
1.0.0

1 year ago