Coder Social home page Coder Social logo

pointsingularity / talkr Goto Github PK

View Code? Open in Web Editor NEW

This project forked from donedeal0/talkr

0.0 0.0 0.0 204 KB

Talkr is the lightest i18n provider for React applications. It supports Typescript, provides autocompletion, has 0 dependencies, and is very easy to use.

Home Page: https://talkr-documentation.netlify.app/

JavaScript 5.34% TypeScript 94.66%

talkr's Introduction

talkr logo

TALKR - DOCUMENTATION

Also see our official website

WHAT IS IT?

talkr autocomplete in action

Talkr is the lightest i18n provider for React applications. It supports Typescript, provides autocompletion, has 0 dependencies, and is very easy to use.

Features:

  • Auto-detect browser language
  • Auto-detect plural rules based on any language
  • Dynamic translations with multiple keys
  • Access deeply nested keys in json translations files
  • Adapts syntax to gender
  • Supports React Native
  • Provides typescript autocompletion for your keys (๐Ÿค˜)

Installation

// with npm
npm install talkr
// with yarn
yarn add talkr

Add translation files

  • Create your JSON translation files.
  • Surround dynamic values by double underscores: __dynamicValue__.
  • To allow automatic plural detection, you will need to pass a count parameter to Talkr's translation function. Talkr will then chose the right word or sentence between zero, one, two, few and many.

๐Ÿค“: Some languages have more complex plural rules, that may require these five options to offer a perfect user experience. For instance, Arabic handle zero, one, two, numbers between 3 and 10 and numbers over 10 as separate entities. If a language doesn't need all these subtleties - like english - you can only write zero, one and many in the JSON file.

{
  "hello": "hello",
  "feedback": {
    "error": "The connection failed",
    "success": "The connection succedeed"
  },
  "user": {
    "describe": {
      "simple": "You are __name__",
      "complex": "You are __name__ and you like __hobby__"
    }
  },
  "idiom": {
    "sovereign": {
      "female": "Long live the Queen!",
      "male": "Long live the King!"
    }
  },
  "message-count": {
    "zero": "you don't have new messages",
    "one": "you have 1 message",
    "many": "you have __count__ messages"
  }
}

Set up

  • In your index file, import your JSON translations
  • Wrap your App with Talkr's Provider
  • Pass it your available languages and your defaultLanguage.
  • You also have the option to let Talkr detect browser's language with the prop detectBrowserLanguage (see [props](#Available props)).
import * as React from "react";
import { createRoot } from "react-dom/client";
import { Talkr } from "talkr";
import App from "./app";
import en from "./i18n/en.json";
import fr from "./i18n/fr.json";

const root = createRoot(document.getElementById("root"));

root.render(
  <Talkr languages={{ en, fr }} defaultLanguage="en">
    <App />
  </Talkr>
);

Simple usage

  • In any component, import Talker's hook useT.
  • Destructure the translation function T from useT
  • Fetch the desired sentence as if you were directly accessing an object, by adding . between each key. Based on the JSON example above, we could print the sentence The connection succedeed by simply writing T("feedback.success")
import React from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T } = useT();
  return (
    <>
      <h1>{T("hello")}</h1>
      <div>{T("feedback.success")}</div>
    </>
  );
}

Dynamic values

  • To handle dynamic translations, just add an object with all necessary dynamic values
  • To make it work, you need to surround the dynamic values by double underscores in your [JSON files](Add translation files) (__dynamicValue__)
"user": {
    "describe": {
      "simple": "You are __name__",
      "complex": "You are __name__ and you like __hobby__"
    }
  }
import React from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T } = useT();
  return (
    <>
      <h1>{T("user.describe.complex", { name: "joe", hobby: "coding" })}</h1>
    </>
  );
}

Plural

  • To handle plural, just add a count property to the object
  • To make it work, you need to provide both zero, one and many values to your JSON files.
"message-count": {
    "zero": "you don't have new messages",
    "one": "you have 1 message",
    "many": "you have __count__ messages"
  }
import React, { useState } from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T } = useT();
  const [count, setCount] = useState(0);
  return (
    <>
      <h1>{T("message-count", { count })}</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </>
  );
}

Gender

  • Some languages have different syntax for masculine and feminine genders.
  • To adapt your sentence accordingly, just pass the param gender: m for male, or gender: f for female.
  • To make it work, you need to provide both male and female values to your JSON files.
"idiom": {
    "sovereign": {
      "female": "Long live the Queen!",
      "male": "Long live the King!"
    }
  }
import React from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T } = useT();
  return (
    <>
      <h1>{T("idiom.sovereign", { gender: "m" })}</h1>
    </>
  );
}

Locale

  • Access and update the locale by using the hook useT()
  • If the provided locale doesn't match any JSON translation files, Talkr will use the defaultLanguage sent to the provider.
import React, { useState } from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T, setLocale, locale } = useT();
  return (
    <>
      <h1>{T("hello")}</h1>
      <p>{locale}</p>
      <button onClick={() => setLocale("fr")}>speak french</button>
    </>
  );
}

AUTOCOMPLETION

Autocompletion for translation keys is available in Typescript projects. Because json must be parsed at compile time, you will need to create your own useAutocompleteT hook with Talkr's Autocomplete type wrapper.

Here's how to do it:

  • Make sure you use Typescript >=4.5.5 (we don't guarantee it will work on older versions)
  • Create a translate.tsx file anywhere in your app(translate.tsx can be named as you want)
  • Import your main language JSON translation (ex: en.json)
  • Instantiate autocompletion with Talkr's Autocomplete
  • Export a useAutocompleteT hook around Talkr's useT()
import { useT, Autocomplete, TParams, tr } from "talkr";
import en from "./en.json";

type Key = Autocomplete<typeof en>;

export const useAutocompleteT = () => {
  const { locale, languages, defaultLanguage } = useT();
  return {
    T: (key: Key, params?: TParams) =>
      tr({ locale, languages, defaultLanguage }, key, params),
  };
};

If you prefer to keep the useT naming, just write:

import { useT as useTr, Autocomplete, TParams, tr } from "talkr";
import en from "./en.json";

type Key = Autocomplete<typeof en>;

export const useT = () => {
  const { locale, languages, defaultLanguage } = useTr();
  return {
    T: (key: Key, params?: TParams) =>
      tr({ locale, languages, defaultLanguage }, key, params),
  };
};

Autocomplete usage

You now have the choice between using your own useAutocompleteT hook - which provides real-time autocompletion - or using Talkr's useT - which doesn't provide autocompletion - in your app.

import { useAutocompleteT } from "./translate";

function App() {
  const { T } = useAutocompleteT();
  return (
    <>
      <h1>{T("feedback.success")}</h1>
      <h4>{T("user.describe.complex", { name: "joe", hobby: "coding" })}</h4>
    </>
  );
}

๐Ÿค“ Pro-tip: since you will need to import useAutocompleteT from translate.tsx, it is highly recommended to add an alias translate to your builder's config and tsconfig.json.

This will allow you to write

import { useAutocompleteT } from "translate" ๐Ÿ‘

instead of

import { useAutocompleteT } from "../../translate" ๐Ÿ‘Ž

Exemples: webpack

resolve: {
  extensions: [".ts", ".tsx", ".js", "jsx", ".json"],
  alias: {
      translate: path.resolve(__dirname, "src/translate/"),
 }

tsconfig

{ "compilerOptions": {
  "paths": {
  "translate/*": ["src/translate/*"]
  }
}}

for other bundlers, please refer to their respective documentations.

React Native

  • Add your provider directly in App.(js|tsx)
import { StyleSheet, Text, View } from "react-native";
import { Talkr } from "talkr";
import en from "./src/i18n/en.json";
import fr from "./src/i18n/fr.json";
import MyComponent from "./src/MyComponent";

export default function App() {
  return (
    <Talkr languages={{ en, fr }} defaultLanguage="en">
      <View style={styles.container}>
        <MyComponent />
      </View>
    </Talkr>
  );
}
  • All the exemples above are valid in React Native. You only have to replace html tags (div, h1, etc.) by Text.
  • Since Intl api is not available in React Native, the count param will only return three types of plural keys: zero, one and many. Please adjust your json files accordingly.
import React, { Text, Button } from "react-native";
import { useState } from "react";
import { useT } from "talkr";

export default function MyComponent() {
  const { T } = useT();
  const [count, setCount] = useState(0);

  return (
    <>
      <Text>{T("hello")}</Text>
      <Text>
        {T("user.describe.complex", { name: "joe", hobby: "coding" })}
      </Text>
      <Text>{T("message-count", { count })}</Text>
      <Button onPress={() => setCount(count + 1)} title="+1" />
    </>
  );
}

Available props

You can pass these props to Talkr's provider

Type Role
languages object object containing all your json files. Typical format: {en: {...}, fr: {...}}
defaultLanguage string default language of your app (a similar key must be included in the language prop)
detectBrowserLanguage boolean if true, Talkr will automatically use browser language and override the defaultLanguage. If the browser language is not included in your available translations, it will switch back to defaultLanguage. Not available in React Native. Use expo-localization to fetch the default user locale instead.

๐Ÿค“: The auto-detect language feature will always return a simple key such as 'fr' instead of 'fr_FR'. Keep things simple and always declare your languages with 2 letters.



CREDITS

DoneDeal0

Mouth logo made by emilegraphics from the Noun Project

talkr's People

Contributors

andrewsmithdev avatar donedeal0 avatar lodmfjord avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.