i18next: learn once - translate everywhere

Overview

i18next: learn once - translate everywhere Tweet

CircleCI Code Climate Coveralls Package Quality cdnjs version npm version David

i18next is a very popular internationalization framework for browser or any other javascript environment (eg. node.js).

ecosystem

i18next provides:

For more information visit the website:

Our focus is providing the core to building a booming ecosystem. Independent of the building blocks you choose, be it react, angular or even good old jquery proper translation capabilities are just one step away.


Gold Sponsors


From the creators of i18next: localization as a service - locize.com

A translation management system built around the i18next ecosystem - locize.com.

locize

With using locize you directly support the future of i18next.


Comments
  • Doesn't work singular/plural forms with a few counts

    Doesn't work singular/plural forms with a few counts

    ๐Ÿ› Bug Report

    I use Trans tag. And I use nesting to create the translations string from few other. So I have to use a few different "count" for every key. I can't use a few counts, because Trans doesn't have such options. So I use "values". And in this case count works fine, context works fine... but "_plural" doesn't work.

    To Reproduce

    Here is code from the page:

                                <Trans
                                    debug={true}
                                    i18nKey="billedAfterTrial"
                                    values={{
                                        currencySign: currencySign,
                                        currentPrice: currentPrice,
                                        count1: periodType.count,
                                        count2: trialType.count,
                                        count3: day,
                                        context1: periodType.context,
                                        context2: trialType.context,
                                        context3: month,
                                    }}
                                >
                                    [$79.99] billed [yearly] after a [7-day] trial period. Contact us via
                                    [email protected] to cancel.
                                </Trans>
    

    Here is the translation keys:

      "X period": "{{count}} week",
      "X period_plural": "{{count}} weeks",
      "X period_month": "{{count}} month",
      "X period_month_plural": "{{count}} months",
      "X period_0": "{{count}} week",
      "X period_1": "{{count}} week",
      "X period_2": "{{count}} week",
      "X period_month_0": "{{count}} month",
      "X period_month_1": "{{count}} month",
      "X period_month_2": "{{count}} month",
    
      "X-period": "{{count}}-week",
      "X-period_month": "{{count}}-month",
    
      "billedAfterTrial": "{{currencySign}}{{currentPrice}} billed every $t(X period, {\"count\": \"{{count1}}\", \"context\": \"{{ context1 }}\" }) after the $t(X-period, {\"count\": \"{{count2}}\", \"context\": \"{{ context2 }}\" }) trial period."
    

    I changed 's' in the "_0, _1, _2" (we use it for Russian), but it doesn't work to. Also, I changed "_plural" to "_other". And nothing works.

    Expected behavior

    I expect that if count1 will be 3, I'll get "billed every 3 months". I get "billed every 3 month"

    // Paste the expected results here
    

    Your Environment

    • i18next version: i.e. 19.9.2
    • os: Mac
    opened by IlliaHohniak-Hexa 49
  • improve docs

    improve docs

    opened by vonovak 47
  • How to use i18next in client side ?

    How to use i18next in client side ?

    Hello Team

    I found your i18next module recently and I'm trying to use it for personal purpose. First of all, thank your for your great job you have done with your module.

    I've successfully tried to use it in the server-side and It works perfectly. Now, I'm trying to use it in the client-side and I unfortunetly don't understand how it must works. I read all the documentation in the i18next.com web site and I didn't find (or understand) a way to use 18next module in the client side. I cannot find enough documentation to use your module in HTML files and I was wondering if you could help me.

    Here is what I'm trying to do:

    I have the following HTML web site:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
    <script type="text/javascript" src="lib/i18next.js"></script>
    <script>
    window.onload = function() {
        i18next.init({
            load:['en-US', 'fr', 'es'],
            fallbackLng: 'en-US',
            ns:'Web_Server',
            defaultNS:'Web_Server',
            backend: {
               loadPath: '/language/static/{{lng}}/{{ns}}.json'
           },
           getAsync:false
        },function(t) {
            var translate = i18next.t("Hello");
            console.log("translate variable = " + translate);
        });
    };
    </script>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf8" />
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
    
            <title>My First Translated Page</title>
            <link rel="stylesheet" href="lib/bootstrap-3.1.1/css/bootstrap.min.css">
            <link rel="stylesheet" href="lib/bootstrap-3.1.1/css/bootstrap-theme.min.css">
            <link rel="stylesheet" href="css/style.css"/>
        </head>
    
        <body background="./img/MS_homepageNEW_bg3.jpg">
    
        <font color="yellow">
        <h1 align="center"> Welcome to My Web Server !!! <br><br> </h1>
        </font>
    
        <p style="text-align:center"><img src = "img/Family.jpg"> </img></p>
        <font color="yellow">
        <h2 align="center"> <br> <br> Choose your favorite application: </h2>
        </font>
    
        <p style="text-align:center">
          <button type="button" class="btn btn-success"> <a href="/user/login"> Application <br> by Me</a></button>
          <button type="button" class="btn btn-warning divider"> <a href="/user/#/RECEPTION"> WebMail <br> by User 2 </button>
        </p>
        </body>
    </html>
    
    

    The following section:

    <script type="text/javascript" src="lib/i18next.js"></script>
    <script>
    window.onload = function() {
        i18next.init({
            load:['en-US', 'fr', 'es'],
            fallbackLng: 'en-US',
            ns:'Web_Server',
            defaultNS:'Web_Server',
            backend: {
               loadPath: '/language/static/{{lng}}/{{ns}}.json'
           },
           getAsync:false
        },function(t) {
            var translate = i18next.t("Hello");
            console.log("translate variable = " + translate);
        });
    };
    </script>
    

    is what I tried to do (by searching examples on google) but when I execute that, the "Hello" string I'm trying to translate has the same value when executing the web page (So the string is not translated and I get in return the original string).

    Can you please tell me what i'm doing wrong or what I have to do to get it work ? Must I install some module in the server side ? Is it possible to store the translations in the client side and if yes, how to do it and how to access to these translations ?

    What configuration (server-side or client-side) i must have to be able, in my html example, to translate the strings (like for example the string in the title of the html page "My First Translated Page", and so on)? I have already the translated strings in json format. As I said, I can easily translate strings in the server-side.

    Thank you very much for your help.

    opened by TitaneBoy 45
  • Find closest language in whitelist

    Find closest language in whitelist

    Is there currently a way to load the closest language available?

    For example: my app contains 2 languages, English (en) and Spanish Mexican (es-MX).

    If a user loads my app with a browser language of es-ES, I would prefer for them to fallback to es-MX rather than en. This seems like common sense, but I can't find a way to do this.

    load: languageOnly allows es-ES to fallback to es, but it does not search for closest match.

    Is there a recommended way to do this?

    opened by dcporter44 40
  • ICU Message Format

    ICU Message Format

    Has anyone ever used ICU Message Format strings within i18next? I am looking for a way to pass an ICU Message string into the t function provided by i18next and receive the proper output string, with the right variable replacement, pluralization, etc. I am aware that i18next supports plurals, variable, and context, but it does so in its own format, whereas ICU Message is a community recognized standard for supporting this logic. The translator that we work with uses ICU Message format so it would be very helpful to just feed these strings directly into i18next, without having to reformat them. Alternatively, if you know of a library that will convert ICU Message strings to the i18next format, that would work as well. Thanks!

    opened by dbendy 40
  • Make the translation function fully type-safe

    Make the translation function fully type-safe

    ๐Ÿš€ Feature Proposal

    With the latest advancements in TypeScript, it's now possible to infer the correct paths from an object type. TypeScript 4.1 introduces recursive conditional types, and there is a PR open that will enable string type concatenation on the type level.

    Motivation

    18next.t accepts arbitrary strings. This allows silly human errors, since it's easy to make a typo.

    Example

    I put together a TypeScript Playground illustrating the improved definition.

    Once https://github.com/microsoft/TypeScript/pull/40336 is merged and released, the improved definition can be put in a separate file loaded only for the ones using the minimum required TypeScript version. In package.json, it should say:

    {
        "typesVersions": {
            ">=4.1.0-0": {
                "*": [
                    /* Path to the new definition */
                ]
            }
        }
    }
    
    doc feature request typescript 
    opened by karol-majewski 33
  • defaultNS with Typescript

    defaultNS with Typescript

    ๐Ÿ› Bug Report

    It seems that i18next doesn't respect type of defaultNS in .d.ts file while using t function

    To Reproduce

    Code example:

    i18next.d.ts

    import { resources, defaultNS } from '../src/i18next';
    
    declare module 'i18next' {
        interface CustomTypeOptions {
            defaultNS: typeof defaultNS;
            resources: typeof resources['en'];
        }
    }
    

    i18next.ts

    import en from './translations/en.json';
    
    export const defaultNS = 'general';
    
    export const resources = {
        en: {
            general: en,
        },
    } as const;
    
    i18n.use(initReactI18next)
        .init({
            resources,
            fallbackLng: 'en',
            ns: ['general'],
            defaultNS,
            compatibilityJSON: 'v3',
            interpolation: {
                escapeValue: false,
                skipOnVariables: false,
            },
            react: {
                useSuspense: false,
            },
        });
    

    Use cases

    // i18next
    i18next.t('common.errors.required') // typescript error
    i18next.t('general:common.errors.required') // valid
    
    // react-i18next
    const { t } = useTranslation();
    t('common.errors.required'); // valid
    

    Expected behavior

    // i18next
    i18next.t('common.errors.required') // valid
    i18next.t('general:common.errors.required') // valid
    

    Your Environment

    • runtime version: react-native 0.70.3
    • i18next version: 12.0.0
    • react-i18next version: 22.0.2
    • os: Mac
    • typescript: 4.8.4
    typescript 
    opened by yuri-lomashko-itechart 31
  • webpack2 - v3.5.x breaks `.use()` method

    webpack2 - v3.5.x breaks `.use()` method

    After upgrading from v3.4.4 to v3.5.0, I am no longer able to run:

    import i18next from 'i18next';
    import LngDetector from 'i18next-browser-languagedetector';
    i18next.use(LngDetector);
    

    Which now returns:

    main.js:90 Uncaught TypeError: _i18next2.default.use is not a function
    

    Printing out i18next indeed shows that the default export method no longer has the use method exposed.

    This does not occur on v3.4.4.

    opened by EvHaus 31
  • Languages with multiple plurals not working

    Languages with multiple plurals not working

    https://www.i18next.com/translation-function/plurals

    Hi I am using the below keys in my local file as given in the docs https://www.i18next.com/translation-function/plurals

    {
         "key": "none",
         "key_0": "zero",
          "key_1": "singular",
          "key_2": "two",
          "key_3": "few",
          "key_4": "many",
          "key_5": "other"
    }
    

    However

    i18next.t('key', {count: 0}); // -> "none"
    
    

    Be it any value of count, I always get none And if i remove "key": "none", from the file then I get the error i18next::translator: missingKey

    Is there anything I am missing ?

    opened by ad1992 30
  • Interpolation escapeValue : false ... not working?

    Interpolation escapeValue : false ... not working?

    I'm trying to substitute a span with text into a string. The string is: Your search for {{1}} returned no results.

    Using this string... let searchTermSpan = '<span class="entered-search">' + searchTerm + '</span>';

    Hoping to get the result: Your search for <span class="entered-search">bad search term</span> returned no results.

    But it is showing that result escaped, not unescaped.

    This is what's in the markup: <h5>{t( "CategoryPage.NoSearchResultsHeaderWithText", { 1: searchTermSpan, interpolation: { escapeValue: false } } )}</h5>

    What am I doing wrong?

    opened by t7m 30
  • question: how to get current language?

    question: how to get current language?

    I couldn't find this in the new API docs:

    What is the replacement for i18n.lng() to get the current (i18n) language (if in whitelist, otherwise fallback) as we were able to get from 1.x version?

    doc 
    opened by MartijnR 29
  • Typesafe Interpolation Variables

    Typesafe Interpolation Variables

    ๐Ÿš€ Feature Proposal

    Enable opt-in typesafe interpolation variables. Given that the user is already using #1504, this will add additional intellisense based on the contents of the string, finding any variable placeholders and requiring values to be passed for each.

    Motivation

    It's easy to miss passing required interpolation variables when translating a string. This will ensure that developers get both real-time Type errors and auto complete for variable names to avoid mistakes at runtime.

    Example

    Example TypeScript sandbox. I wrote this code to make typesafe URL path variables and realized it could be used with very minor tweaks here too. It'd be amazing if this could be integrated into the core library.

    Notes

    • I know the variable placeholders can be extremely complex. This feature would only be usable for those with simple placeholders ({{name}}) and nothing more. As a result, it needs to be opt-in as it won't work for everyone. I believe this is still valuable as simple placeholders covers a majority of users.
    typescript 
    opened by CreativeTechGuy 0
  • 22.4.5 broke the types

    22.4.5 broke the types

    ๐Ÿ› Bug Report

    Updating from 22.4.4 to 22.4.5 broke the following code.

    To Reproduce

          interface TransDataMap {
            'Greeting': { name: string; };
          }
          function trans<K extends keyof TransDataMap>(el: HTMLElement, key: K, data: TransDataMap[K]) {
            i18next.init((err, t) =>
              el.textContent = err
                ? ''
                : t(key, data) ?? ``);
          }
    

    Expected behavior

    pass

    Your Environment

    • runtime version: v19
    • i18next version: 22.4.5
    • os: Windows
    typescript 
    opened by falsandtru 0
  • documentation help

    documentation help

    Hello, I can't figure out how to translate to