0.0.7 β€’ Published 11 months ago

@rustling-pines/typesafe-translator-react v0.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Typesafe Translator for React

A lightweight, type-safe translation library for React that simplifies internationalization (i18n) with TypeScript. Supports lazy loading, automatic generation of locale files, and string interpolation with compile-time safety.


Features

  • πŸ›‘ Type Safety: Ensures compile-time validation of translation keys and placeholders, reducing runtime errors.
  • 🌍 Dynamic Locale Switching: Switch between locales seamlessly at runtime.
  • πŸ”„ String Interpolation: Supports named ({key}) and positional ({0}) placeholders in translations.
  • πŸš€ Lazy Loading: Fetch locale files on demand, reducing initial bundle size.
  • πŸ›  Automatic Locale Generation: Generate locale JSON files during the build step.
  • πŸ“¦ Lightweight & Modular: Minimal dependencies with a modular design.
  • πŸ”— React-Ready: Built for React (supports React >=16.8).

EXAMPLE

 // βœ… Valid key
 <h1>{t.APP_TITLE()}</h1>

 // ❌ Invalid key (will throw a compile-time error)
 <h1>{t.INVALID_KEY()}</h1>

Installation

npm install @rustling-pines/typesafe-translator-react

Sample Project Structure

client-app/
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ translations/    # Automatically generated
β”‚   β”‚   β”œβ”€β”€ en-us.json
β”‚   β”‚   β”œβ”€β”€ de.json
β”‚   β”‚   └── fr.json
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ translations
β”‚   β”‚   └── validatedTranslations.ts   # Client-defined translations (default location)
β”‚   β”œβ”€β”€ App.tsx
β”‚   └── pages/
β”‚       └── HomePage.tsx
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── README.md

Usage

Step 1: Define Locales and Translation Keys

Create a validatedTranslations.ts file to define your supported locales and translation keys.

NOTE: Configure Environment File (Optional)

If you want to specify a custom location or name for validatedTranslations.ts, create a .env file in the root of your project and add the key: VALIDATED_TRANSLATIONS_PATH=custom/path/to/validatedTranslations

import type { ITranslation } from "@rustling-pines/typesafe-translator-react";

// Define the locales as both a type and a value
export const locales = ["en-us", "de", "fr"] as const;
export type TLocales = typeof locales[number];

export const keys = {
    APP_TITLE: "APP_TITLE",
    LOGIN_BUTTON_TITLE: "LOGIN_BUTTON_TITLE",
} as const;

// Define translations using the ITranslation type
export const validatedTranslations: ITranslation<TLocales>[] = [
    {
        key: keys.APP_TITLE, // Use `keys` for type safety
        "en-us": "Welcome, {name}!",
        "de": "Willkommen, {name}!",
        "fr": "Bienvenue, {name}!",
    },
    {
        key: keys.LOGIN_BUTTON_TITLE, // Use `keys` for type safety
        "en-us": "Login as {role} & {0}",
        "de": "Anmelden als {role} & {0}",
        // ❌ Missing 'fr' will trigger a TypeScript error
    },
];

Step 2: Add Scripts to Generate Translation Files

Add the following scripts to your package.json:

"scripts": {
    "generate-translations": "translation-cli generate",
    "build": "npm run generate-translations && react-scripts build"
}

Step 3: Wrap Your App with TranslationProvider

In your App.tsx, wrap your application with the TranslationProvider and pass the locales and keys.

import React from "react";
import { TranslationProvider } from "@rustling-pines/typesafe-translator-react";
import { locales, keys } from "src/translations/validatedTranslations";
import HomePage from "./pages/HomePage";

const App: React.FC = () => (
    <TranslationProvider providedLocales={locales} providedKeys={keys}>
        <HomePage />
    </TranslationProvider>
);

export default App;

Step 3: Use Translations in Components

Access translations and change locales using the useTranslationService hook.

import React from "react";
import { useTranslationService } from "@rustling-pines/typesafe-translator-react";

const HomePage: React.FC = () => {
    const { t, setLocale } = useTranslationService();

    return (
        <div>
            {/* Switch locales */}
            <button onClick={() => setLocale("en-us")}>English</button>
            <button onClick={() => setLocale("de")}>German</button>
            <button onClick={() => setLocale("fr")}>French</button>

            {/* Access translations */}
            <h1>{t.APP_TITLE({ name: "John" })}</h1>
            <button>{t.LOGIN_BUTTON_TITLE({ role: "Admin", 0: "Tomorrow" })}</button>
        </div>
    );
};

export default HomePage;

Example of Autogenerated Translation Files

Translation files are automatically generated Here’s an example:

public/translations/en-us.json

{
    "APP_TITLE": "Welcome, {name}!",
    "LOGIN_BUTTON_TITLE": "Login as {role} & {0}"
}

public/translations/de.json

{
    "APP_TITLE": "Willkommen, {name}!",
    "LOGIN_BUTTON_TITLE": "Anmelden als {role} & {0}"
}

public/translations/fr.json

{
    "APP_TITLE": "Bienvenue, {name}!",
    "LOGIN_BUTTON_TITLE": "Connexion en tant que {role} & {0}"
}

Requirements

  • React: Version >=16.8 (supports hooks)
  • TypeScript: Version >=4.1

Contributing

Contributions are welcome! If you’d like to report a bug or suggest a feature, feel free to open an issue or submit a pull request.


License

This project is licensed under the MIT License - see the LICENSE file for details.