Internationalization for react done right. Using the i18next i18n ecosystem.

Overview

react-i18next Tweet

CircleCI Code Climate Coverage Status Quality dependencies devdependencies

IMPORTANT:

Master Branch is the new v10 using hooks.

$ v10.0.0
npm i react-i18next

react-native: To use hooks within react-native, you must use react-native v0.59.0 or higher

For the legacy version please use the v9.x.x Branch

$ v9.0.10 (legacy)
npm i [email protected]

Documentation

The documentation is published on react.i18next.com

What will my code look like?

Before: Your react code would have looked something like:

...
<div>Just simple content</div>
<div>
  Hello <strong title="this is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
</div>
...

After: With the trans component just change it to:

...
<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
...

Head over to the interactive playground at codesandbox.

📖 What others say

Why i18next?

  • Simplicity: no need to change your webpack configuration or add additional babel transpilers, just use create-react-app and go.
  • Production ready we know there are more needs for production than just doing i18n on the clientside, so we offer wider support on serverside too (nodejs, php, ruby, .net, ...). Learn once - translate everywhere.
  • Beyond i18n comes with locize bridging the gap between developement and translations - covering the whole translation process.

ecosystem

Localization workflow

Want to learn more about how seamless your internationalization and translation process can be?

video

watch the video

Installation

Source can be loaded via npm or downloaded from this repo.

# npm package
$ npm install react-i18next
  • If you don't use a module loader it will be added to window.reactI18next

Examples

v9 samples

Requirements

  • react >= 16.8.0
  • react-dom >= 16.8.0
  • react-native >= 0.59.0
  • i18next >= 10.0.0 (typescript users: >=17.0.9)

v9

Core Contributors

Thanks goes to these wonderful people (emoji key):


Jan Mühlemann

💻 💡 📖 💬

Adriano Raiano

💻 💡 📖 💬

Tiger Abrodi

💬 💻 👀

Pedro Durek

💻 💡

This project follows the all-contributors specification. Contributions of any kind are welcome!


Gold Sponsors


localization as a service - locize.com

Needing a translation management? Want to edit your translations with an InContext Editor? Use the original provided to you by the maintainers of i18next!

locize

With using locize you directly support the future of i18next and react-i18next.


Comments
  • Future of the NextJs example

    Future of the NextJs example

    We can discuss the future of the NextJs example here, as it has gotten a lot of attention lately, and has some shortcomings.

    Current problems:

    1. Language subpaths are causing a lot of issues
    2. Initial language and the translation HOCs are not working well together

    Future goals:

    1. Refactor server and Link usage to match this example, thus preventing 404s and fixing #569
    2. Unify translation workflow, and make it less prone to user error: expose a single withNamespaces HOC that supports tree traversal, and make it abundantly clear that this is the only way to translate content. Fixes issues like #603.

    I believe the best way forward is a complete rewrite to simplify a few things. The first step is to decide if we want to support language subpaths at all.

    Are there any other issues people are aware of currently?

    I would like to compile a full list of current issues we are facing here, as well as any new features, or features we plan to remove, before proceeding with any work on the NextJs example.

    Only then can we have a clear plan and execute it.

    enhancement next.js / SSR 
    opened by isaachinman 67
  • I18nextWithTranslation suspended while rendering, but no fallback UI was specified

    I18nextWithTranslation suspended while rendering, but no fallback UI was specified

    I wrote it up on Stack Overflow before I figured out how to post here.

    https://stackoverflow.com/questions/54951422/error-i18nextwithtranslation-suspended-while-rendering-but-no-fallback-ui-was

    I am using v10 and only using the HOC withTranslation. It looks so simple, yet I am not able to get it working. I suspect there is something simple.

    can not reproduce 
    opened by margozzi 57
  • False warning about accessing t function before calling init

    False warning about accessing t function before calling init

    Describe the bug I'm having a warning that I think is a false positive. I get the thousands of the following warning: i18next.js:27 i18next::translator: key "xxx" for namespace "translation" won't get resolved as namespace was not yet loaded This means something IS WRONG in your application setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!

    I think it's a false positive for 3 reasons:

    1. I do call init() before calling ReactDOM.render().
    2. I was working until I updated to v10.12.4 (or maybe 10.12.5, not sure...).
    3. All my localized strings are correctly displayed in my app.

    Before all the warnings, the console prints this:

    i18next: languageChanged fr-FR
    i18next: initialized {debug: true, initImmediate: true, ns: Array(1), defaultNS: "translation", fallbackLng: Array(1), …}
    

    Occurs in following versions npm 6.12.0 react-i18next 10.13.2

    OS (please complete the following information):

    • Device: PC Windows 10
    • Browser: Chrome 78.0.3904.70 (Build officiel) (64 bits)
    opened by Robloche 54
  • missingKey issue

    missingKey issue

    Hi, i get this console error in any interaction with my view 'i18next::translator: missingKey fr backoffice'

    even i tried ti put react: { wait: true, }

    but this did not work

    Help!

    opened by wijdench 54
  • Make the translation function fully type-safe

    Make the translation function fully type-safe

    With Typescript 4.1, now it is possible to use recursive conditional type and template literal string. This PR aims to make the t function fully typed and supporting single and multiple namespaces. It works with useTranslation (hooks), withTranslation (HoC), Trans Component and Translation (render prop).

    How to use it

    You just have to rely on type augmentation technique to override the default Resources with the resource language object.

    For example:

     // src/i18n/config.ts
    export const resourcesEN = {
      earnings: {
        header: {
          title: 'Earnings',
          subTitle: 'See your Earnings'
        },
        notes: 'Balance'
      }
    };
    
    i18n.use(initReactI18next).init({
      resources: {
        en: resourcesEN,
      },
    });
    
    

    Type augmentation

    // @types/react-i18next/index.d.ts
    import "react-i18next";
    import resourcesEN from "../../src/i18n/config";
    
    declare module "react-i18next" {
      type DefaultResources = typeof resourcesEN;
      interface Resources extends DefaultResources {}
    }
    

    And that's all!!! it works like magic! I've prepared a few examples using useTranslation.

    Using single and multiple namespaces: https://tsplay.dev/gWozjm

    Array case within the resources JSON: https://tsplay.dev/nmq0ZN

    Without Namespace: https://tsplay.dev/rw21xW

    Below is the diff of the changes that I made: https://gist.github.com/pedrodurek/b23c17bebd9619b0dc0651bc3949a82e/revisions#diff-7aa4473ede4abd9ec099e87fec67fd57afafaf39e05d493ab4533acc38547eb8

    Let me know if you want me to change anything, thank you guys! I hope this can help everyone who relies on i18next and typescript.

    Checklist

    • [x] only relevant code is changed (make a diff before you submit the PR)
    • [x] run tests npm run test
    • [ ] tests are included
    • [ ] documentation is changed or added
    opened by pedrodurek 43
  • Error occurs on render when using tOptions.interpolation

    Error occurs on render when using tOptions.interpolation

    🐛 Bug Report

    With the merge of my PR https://github.com/i18next/react-i18next/pull/1204, when I try to pass interpolation to tOptions, an error occurs. When I remove the tOptions prop that I passed in, then it works, which is very weird :thinking:.

    In the console React on the first few lines says:

    The above error occurred in the <br> component:
        in br (at dashboard-greeting/index.tsx:40)
        in Trans (at dashboard-greeting/index.tsx:34)
    

    In the very last line of console React says React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.

    To Reproduce

    To reproduce this you would have to use Trans like this:

    <Trans
            i18nKey="home:UserGreetingHeadline"
            defaults="Hallo {{ firstName }},<br/>
            willkommen auf <bold>meine</bold>tonies, hier kannst du ganz zentral
            Deine Toniesammlung und Tonieboxen verwalten."
            values={{ firstName: 'Tiger<no>' }}
            components={{ br: <br />, bold: <strong /> }}
            tOptions={{ interpolation: { escapeValue: true } }}
          />
    

    As for the i18nKey, you do not have to specifically put it into a home.json file :+1:.

    Expected behavior

    I do expect this to at least be able to render, with or without tOptions prop. I still find it very strange that it is working when I do not use the tOptions prop.

    PS. I am happy to work on whatever has to be fixed in case this happens because of either my last PR or if anything else has to be changed :two_hearts:.

    Pictures

    Picture of the error:

    Screenshot from 2020-12-03 07-50-13

    Picture when not using tOptions prop, then it works apparently :thinking: :

    Here the message is also broken because of the HTML tags in firstName :cry:. Screenshot from 2020-12-03 07-51-35

    Your Environment

    • runtime version: i.e. node v14.15.0
    • i18next version: i.e. 11.7.4
    • os: Linux, Ubuntu
    stale 
    opened by narutosstudent 42
  • v10: hooks and suspense

    v10: hooks and suspense

    The plan is to provide both versions in the future:

    • v10 will be the version having the new hooks and suspense version only
    • v9 will be the last major version having the current react-i18next available (will go into maintenance mode -> only bug fixes - no new features)

    We for sure will have to maintain v9 for a while.

    TODO:

    • [x] rename useT -> useTranslation, withT -> withTranslations
    • [x] report namespaces functionality (auto enabled under the hood - accessible via getFunction)
    • [x] handle initialStore, initialLanguage (where? existing Hook, new explicit useSSRI18n Hook, new explicit withSSRI18n HOC)
    • [x] rename useReactI18n with useReactI18next here: https://github.com/i18next/react-i18next/blob/master/src/hooks/context.js#L35
    • [x] create a next.js sample as proof of concept: getInitialProps as a HOC, or just a plain function provided to get that values for initialI18nStore and initialLanguage from react-i18next? (https://github.com/i18next/react-i18next/issues/671 seems a prove of working as expected)
    • [x] add tests for all the new stuff
    • [x] add typings for typescript

    Release winter 2018/19: https://reactjs.org/blog/2018/11/27/react-16-roadmap.html (won't be 16.7!!! https://reactjs.org/blog/2018/12/19/react-v-16-7.html)

    Release seems to be 4th of February: https://github.com/facebook/react/pull/14692

    v10 (hooks) 
    opened by jamuhl 42
  • React router unmounts, set state and change language not playing well together

    React router unmounts, set state and change language not playing well together

    Describe the bug When changing language (with XHR backend setup), changing the route in react-router and setting a state value I get the well-known warning below:

    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

    I'm guessing it's due to the async XHR call to the language file because it only happens on the first load.

    I tried to go around the issue but couldn't nail it so far.

    I set up a code sandbox example here: https://codesandbox.io/s/6vm8o90jpk

    Note: I'm not sure this belongs to this repo or not, if you want me to move it somewhere else please let me know.

    Thanks for your help!

    Occurs in react-i18next version 10.5.1

    To Reproduce Steps to reproduce the behavior:

    1. Go to 'https://6vm8o90jpk.codesandbox.io/en/hello'
    2. Open the console
    3. Click on 'Change lang'
    4. See the error in console

    Expected behaviour A clear and concise description of what you expected to happen.

    Screenshots http://recordit.co/tKnLmlyKMg

    OS :

    • Device: MBP 2017 15"
    • Browser: Chrome 72.0.3626.121
    opened by johnraz 40
  • useTranslation breaking

    useTranslation breaking "Rules of Hooks"

    Describe the bug We're using the new useTranslation hook in our components. However, during development React complains that some hooks have been rendered conditionally and that the amount of hooks in a component has changed. When switching back to the Translation HOCs the error disappeared, so I assume it's because of this line here:

    https://github.com/i18next/react-i18next/blob/ece439751c09b0cbe8170f07bfe79617ce589cb8/src/useTranslation.js#L14

    Conditionally rendering hooks break the "Rules of Hooks", so this should be refactored to always render all hooks.

    Our component does not render any hooks conditionally, I have checked thrice.

    Occurs in react-i18next version 10.0.5

    Expected behaviour No error to occur and no hooks rendering conditionally.

    Screenshots image

    OS (please complete the following information):

    • Device: MBP 2015, Latest MacOS
    • Browser: Chrome 72.0.3626.96
    opened by NeoLegends 40
  • React.lazy usage with useTranslation hook

    React.lazy usage with useTranslation hook

    Describe the bug I have a few pages that use React.lazy. It seems that on those pages, my translations aren't loaded (or maybe are loaded after the component renders).

    I've tried several variations of setting react: { useSuspense: false} and useTranslation('translations', {useSuspense: false})` but have had no success getting translations to display.

    I'm not sure if this is a bug, or a misconfiguration on my part.

    Occurs in react-i18next version 10.6.1

    To Reproduce

    1. Use the following config: i18n.ts
    import i18n from 'i18next';
    import LanguageDetector from 'i18next-browser-languagedetector';
    import Backend from 'i18next-xhr-backend';
    import {initReactI18next} from 'react-i18next';
    
    i18n
      .use(Backend)
      .use(LanguageDetector)
      .use(initReactI18next)
      .init({
        defaultNS: 'translation',
        fallbackLng: 'en',
        interpolation: {
          escapeValue: false, // not needed for react as it escapes by default
        },
        load: 'languageOnly',
        saveMissing: true,
      });
    
    export default i18n;
    

    Optionally add react: { useSuspense: false}

    1. Lazy load a component that uses the useTranslation hook:
    const NotFound = React.lazy(() => import('./NotFound'));
    
    import React from 'react';
    import {useTranslation} from 'react-i18next';
    
    const NotFound: React.SFC = () => {
      const [t] = useTranslation();
      return <h1 data-testid='not-found-heading'>{t('not-found')}</h1>;
    };
    
    export default NotFound;
    

    Optionally use useTranslation('translations', {useSuspense: false})`

    Expected behaviour I expect to see my translations, not the key of the translation.

    OS (please complete the following information):

    • Device: 2016 MBP 13" macOS 10.14.4
    • Browser: Firefox Developer Edition 67.0b6
    opened by DevanB 37
  • Can't find a way to make it work, error with 'options' or 'getFixedT'

    Can't find a way to make it work, error with 'options' or 'getFixedT'

    Hi,

    I'm trying to configure i18next with my React project and I can't make it work at all..

    Whatever I try, I get either this :

    TypeError: Cannot read property 'options' of undefined
        at new Translate (/Users/ank49/Documents/React Projects/Portfolio React i18n/node_modules/react-i18next/dist/commonjs/translate.js:65:32)
    

    or this :

    TypeError: Cannot read property 'getFixedT' of undefined
        at Translate.componentWillMount (/Users/ank49/Documents/React Projects/Portfolio React i18n/node_modules/react-i18next/dist/commonjs/translate.js:84:46)
    

    I initialized my i18n with the React and WebPack 2 example as the following :

    import i18n from 'i18next'
    import LanguageDetector from 'i18next-browser-languagedetector'
    
    i18n.use(LanguageDetector)
        .init({
          loadPath:    'locales/{{lng}}/{{ns}}.json',
          preload:     ['en-US', 'fr-FR'],
          fallbackLng: 'fr-FR',
          // wait: true, // globally set to wait for loaded translations in translate hoc
    
          // have a common namespace used around the full app
          ns: ['common',
            'navbar',
            'footer',
            'header',
            'about',
            'experience',
            'skills',
            'p_app',
            'p_web',
            'cv',
            'social',
            'events',
            'contact',
            'support'],
    
          defaultNS: 'common',
    
          debug: true,
    
          // cache: {
          //   enabled: true
          // },
    
          interpolation: {
            escapeValue: false, // not needed for react!!
          },
          wait:          true,
        })
    
    export default i18n
    

    and my component I'm trying to translate is as follow :

    import React, { Component } from 'react'
    import PropTypes from 'prop-types'
    import withStyles from 'isomorphic-style-loader/lib/withStyles'
    import Typist from 'react-typist'
    import { translate } from 'react-i18next'
    import { Parenthesis } from '../../components'
    
    import style from './header.scss'
    
    class Header extends Component {
      static propTypes = {
        t: PropTypes.func.isRequired,
      }
    
      render() {
        const { t } = this.props
    
        return (
          <div>
    
            <section className="header">
              <div className="header_content">
                <div className="header_content_inner">
                  <h1 id="homeTextHead">{t('header.title')}</h1>
                  <hr className="bg_dark"/>
                  <br/>
                  <Typist avgTypingDelay={90} className="typed_text">
                    {t('header.name')}
                    <br/>
                    <Parenthesis>{t('header.pseudo')}</Parenthesis>
                    <br/>
                    <br/>
                    {t('header.description')}
                  </Typist>
                </div>
              </div>
            </section>
    
          </div>
        )
      }
    }
    
    export default withStyles(style)(translate(['header'], { wait: true })(Header))
    

    I also tried with the decorator but I got the same issues..

    @translate(['header'])
    class Header extends Component {
    ...
    }
    
    export default withStyles(style)(Header)
    

    Any help is welcome, thanks in advance guys !

    opened by Pomanks 36
  • Inaccurate Trans unescape test label

    Inaccurate Trans unescape test label

    https://github.com/i18next/react-i18next/blob/b93be8e860b9418b072142f1dd451196bd87ba76/test/trans.render.spec.js#L631-L645

    The referenced test specifies that &lt; and &gt; should be unescaped to render as < and >, however the rendered result in the test has these characters still displayed as entities

    stale 
    opened by wjramos 2
  • You are passing an undefined module! Please check the object you are passing to i18next.use()

    You are passing an undefined module! Please check the object you are passing to i18next.use()

    🐛 Bug Report

    I followed the usage example files i18n with jest. I created the mock file, included in moduleNameMapper, but when I go to test a component that uses i18n, I get this error: You are passing an undefined module! Please check the object you are passing to i18next.use()

    Captura de Tela 2022-10-27 às 12 31 14

    To Reproduce

    /src/test/__mocks__/react-i18next.js:

    const React = require('react');
    const reactI18next = require('react-i18next');
    
    const hasChildren = node => node && (node.children || (node.props && node.props.children));
    
    const getChildren = node =>
      node && node.children ? node.children : node.props && node.props.children;
    
    const renderNodes = reactNodes => {
      if (typeof reactNodes === 'string') {
        return reactNodes;
      }
    
      return Object.keys(reactNodes).map((key, i) => {
        const child = reactNodes[key];
        const isElement = React.isValidElement(child);
    
        if (typeof child === 'string') {
          return child;
        }
        if (hasChildren(child)) {
          const inner = renderNodes(getChildren(child));
          return React.cloneElement(child, { ...child.props, key: i }, inner);
        }
        if (typeof child === 'object' && !isElement) {
          return Object.keys(child).reduce((str, childKey) => `${str}${child[childKey]}`, '');
        }
    
        return child;
      });
    };
    
    const useMock = [k => k, {}];
    useMock.t = k => k;
    useMock.i18n = {};
    
    module.exports = {
      // this mock makes sure any components using the translate HoC receive the t function as a prop
      withTranslation: () => Component => props => <Component t={k => k} {...props} />,
      Trans: ({ children }) =>
        Array.isArray(children) ? renderNodes(children) : renderNodes([children]),
      Translation: ({ children }) => children(k => k, { i18n: {} }),
      useTranslation: () => useMock,
    
      // mock if needed
      I18nextProvider: reactI18next.I18nextProvider,
      initReactI18next: reactI18next.initReactI18next,
      setDefaults: reactI18next.setDefaults,
      getDefaults: reactI18next.getDefaults,
      setI18n: reactI18next.setI18n,
      getI18n: reactI18next.getI18n,
    };
    

    jest.config.js

    moduleNameMapper: {
        'react-i18next': '<rootDir>/src/test/__mocks__/react-i18next.js',
      },
    

    Your Environment

    • node: v16.14.2
    • i18next version: ^21.6.16
    • os: Mac
    • react: 18.1.0
    • next: 12.1.6
    can not reproduce 
    opened by lucasfelixc 14
  • Unable to initialize TFunction for testing after latest version

    Unable to initialize TFunction for testing after latest version

    🐛 Bug Report

    Hi. I've initialized TFunction in my tests before i18next v22 and i18next v12, but I'm not able to do that after the upgrade.

    To Reproduce

    Code before the upgrade

    import { TFunction } from 'react-i18next';
    
    import { translationResources } from '../../constants';
    
    const translation: { [key: string]: string } = translationResources.fi.translation;
    
    const t: TFunction<'translation', undefined> = (str: string) => translation[str];
    

    Code after the upgrade

    import { TFunction } from 'i18next';
    
    import { translationResources } from '../../constants';
    
    const translation: { [key: string]: string } = translationResources.fi.translation;
    
    const t: TFunction<'translation', undefined> = (str: string) => translation[str];
    

    The error

    Type '(str: string) => string' is not assignable to type 'TFunction<"translation", undefined>'.
      Type 'string' is not assignable to type 'TFunctionDetailedResult<any>'.
    

    Expected behavior

    I expect to be able to initialize TFunction

    Your Environment

    • runtime version: node v16
    • i18next version: 22.0.2
    • os: macOS
    • typescript: 4.7.4
    typescript 
    opened by janpe 7
  • Error: Unable to resolve module ./withSSR

    Error: Unable to resolve module ./withSSR

    None of these files exist:

    • node_modules/react-i18next/dist/commonjs/withSSR(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.svg|.native.svg|.svg)
    • node_modules/react-i18next/dist/commonjs/withSSR/index(.native|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.svg|.native.svg|.svg) 106 | var _I18nextProvider = require("./I18nextProvider"); 107 |

    108 | var _withSSR = require("./withSSR"); | ^ 109 | 110 | var _useSSR = require("./useSSR"); 111 |

    stale 
    opened by mantegnous 2
  • Typescript safer interpolation

    Typescript safer interpolation

    🚀 Feature Proposal

    The goal here is to improve the type the TFunction so that if we have variables in our translation file, the TFunction is aware of it and help prevent missing keys or extra keys.

    Motivation

    Let's say we have this json file:

    {
      "key1": "text",
      "key2": "text with {{var}}"
    }
    

    Then if we do

    t("key1") // works
    t("key1", { unknown: "fail plz" }) // fails
    t("key2") // fails
    t("key2", { var: "cool" }) // works
    

    Additional context:

    I am aware that is could be a dupe of https://github.com/i18next/react-i18next/issues/1423. But I don't think the lib should wait for the feature to be implemented because there is workarounds for it. In our project, we automatically type the json by generating an associated .d.ts with the proper type.

    So the json in our example has the following type:

    declare const $defaultExport: {
      "key1": "text",
      "key2": "text with {{var}}"
    }
    

    So the type DefaultResources = TypeOptions['resources']; has more informations and we should use that.

    Proposal:

    The previous definition was:

    export interface TFunction<N extends Namespace = DefaultNamespace, TKPrefix = undefined> {
      <
        TKeys extends TFuncKey<N, TKPrefix> | TemplateStringsArray extends infer A ? A : never,
        TDefaultResult extends TFunctionResult | React.ReactNode = string,
        TInterpolationMap extends object = StringMap
      >(
        key: TKeys | TKeys[],
        options?: TOptions<TInterpolationMap> | string,
      ): TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>;
      <
        TKeys extends TFuncKey<N, TKPrefix> | TemplateStringsArray extends infer A ? A : never,
        TDefaultResult extends TFunctionResult | React.ReactNode = string,
        TInterpolationMap extends object = StringMap
      >(
        key: TKeys | TKeys[],
        defaultValue?: string,
        options?: TOptions<TInterpolationMap> | string,
      ): TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>;
    }
    

    And the new one is:

    type Keys<S extends string> = S extends '' ? [] :
      S extends `${infer _}{{${infer B}}}${infer C}` ? [B, ...Keys<C>] : []
    
    export interface TFunction<N extends Namespace = DefaultNamespace, TKPrefix = undefined> {
      <
        TKeys extends TFuncKey<N, TKPrefix> | TemplateStringsArray extends infer A ? A : never,
        TDefaultResult extends TFunctionResult | React.ReactNode = string,
      >(
        key: TKeys | TKeys[],
        ...defaultValueOrOptions: Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number] extends never ? ([] | [TOptionsBase | string] | [string, TOptionsBase | string]) : [TOptions<Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number>>] | [string, TOptions<Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number>>]
      ): TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>;
    }
    

    Let's analyse the changes here:

    Keys<S> is here to get the value of variables in the string. So Keys<"string"> is [] and Keys<"{{var}} foo"> is ["var"]. Keys<"{{var1}} bar {{var2}}">[number] is "var1" | "var2". Keys<"string">[number] is never.

    We changed TInterpolationMap to Record<Keys<DefaultResources[N][TKeys]>[number], string | number>.

    The type we want for TInterpolationMap is a map { variables: value }. To get the variables we need to use Keys<S> on the string value. The string value is the current implementation of TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>. If we change the TFuncReturn value to interpolate the result like the Interpolate in this SO , this need to change.

    We directly use Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number> instead of TInterpolationMap extends to avoid the possible extra keys.

    Since now the argument of the TFunction is optional based on the generics, I did not find a better way that to use spread operator. (SO) leading to a less readable type.

    Let's analyse it:

    ...defaultValueOrOptions: Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number] extends never ? ([] | [TOptionsBase | string] | [string, TOptionsBase]) : [TOptions<Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number>> | string] | [string, TOptions<Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number>> | string]
    

    Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number] extends never is a check to know if there is any variables. If there is no variables:

    defaultValueOrOptions can be

    • no args: []
    • one arg: the base options with no extra key or default value.
    • two args: the default value and the base options with no extra keys.

    If there is variables, the defaultValueOrOptions can be

    • one arg: the base options with the variables map (TOptions<Record<Keys<TFuncReturn<N, TKeys, TDefaultResult, TKPrefix>>[number], string | number>>)
    • two args: the default value and the options with the variables map.

    I did not test what this code will result if the json is not typed with real string. But maybe it could be something like:

    type Keys<S extends string> = string extends S ? string[] : S extends '' ? [] :
      S extends `${infer _}{{${infer B}}}${infer C}` ? [B, ...Keys<C>] : []
    

    In our project, we don't use nested keys so I did not test that.

    Please don't hesitate to point out any mistakes or improvement. I would love to have this changes integrated or have a better support with a fully typed json.

    typescript pr hold 
    opened by MrChoclate 5
  • This JSX tag's 'children' prop expects a single child of type 'ReactI18NextChild | Iterable<ReactI18NextChild>' when using `allowObjectInHTMLChildren`

    This JSX tag's 'children' prop expects a single child of type 'ReactI18NextChild | Iterable' when using `allowObjectInHTMLChildren`

    🐛 Bug Report

    After upgrading to React v18 and Reacti18Next to v11.18, I had an issue with objects not being accepted inside the Trans component, something similar to this. The fix for that was to add the allowObjectInHTMLChildren property, which fix that issue, but it lead to another issue. Now, when I try to have the result of a t function along with some other strings inside a p or span component, I get the error

    This JSX tag's 'children' prop expects a single child of type 'ReactI18NextChild | Iterable<ReactI18NextChild>' when using `allowObjectInHTMLChildren
    

    To Reproduce

    Codesandbox - https://codesandbox.io/s/react-i18next-type-issue-uidhq7 Please check the error on src/App.tsx:10

    <p>{t("simpleContent")} with extra stuff</p>
    

    Proposed Solution

    I tried playing around with the types in the library and it seems like changing node_modules/react-i18next/ts4.1/index.d.ts:108 as follows will fix this.

    declare module 'react' {
      interface HTMLAttributes<T> {
        children?: ReactI18NextChild | ReactI18NextChild[];
      }
    }
    

    The problem, at least for me, seems to be with Iterable<ReactI18NextChild> not working as expected for multiple children

    typescript 
    opened by davehowson 26
Owner
i18next
Organization for i18next.com and anything i18next related.
i18next
Code for How to Internationalize (i18n) a React App with Transifex

Code for How to Internationalize (i18n) a React App with Transifex Code for How to Internationalize (i18n) a React App with Transifex Tutorial Prerequ

Shahed Nasser 1 Jan 20, 2022
A weather app done with React. Allows you to make a search for the current weather by simply typing "common knowledge" cities and save them to favourites on local storage.

Simpliest Weather React-App A weather app done with React. Allows you to make a search for the current weather by simply typing "common knowledge" cit

Larry Noriega 3 Aug 24, 2022
Starter kit with Next.js, Chakra-UI, Framer-Motion in Typescript. Internationalization, SEO, Components, Theme (dark/light) and more...

Typescript Next.js Chakra-UI Framer-Motion Starter Kit Start with a powerful template ⚡️ Table of contents Getting started Paths & Files Useful depend

Alexandre Gossard 39 Oct 14, 2022
nextjs-multiple-page-i18n

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Mahabub Islam Prio 1 Sep 10, 2022
my best project right now ❤️

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

baha-sniper-py 1 Dec 20, 2021
Recoil is an experimental state management library for React apps. It provides several capabilities that are difficult to achieve with React alone, while being compatible with the newest features of React.

Recoil · Recoil is an experimental set of utilities for state management with React. Please see the website: https://recoiljs.org Installation The Rec

Facebook Experimental 18k Nov 22, 2022
React features to enhance using Rollbar.js in React Applications

Rollbar React SDK React features to enhance using Rollbar.js in React Applications. This SDK provides a wrapper around the base Rollbar.js SDK in orde

Rollbar 38 Sep 20, 2022
Soft UI Dashboard React - Free Dashboard using React and Material UI

Soft UI Dashboard React Start your Development with an Innovative Admin Template for Material-UI and React. If you like the look & feel of the hottest

Creative Tim 179 Nov 28, 2022
React-app - Building volume rendering web app with VTK.js,react & HTML Using datasets provided in vtk examples (head for surface rendering and chest for ray casting)

SBE306 Assignment 4 (VTK) data : Directory containing Head and Ankle datasets Description A 3D medical viewer built with vtk-js Team Team Name : team-

Mustafa Megahed  2 Jul 19, 2022
a more intuitive way of defining private, public and common routes for react applications using react-router-dom v6

auth-react-router is a wrapper over react-router-dom v6 that provides a simple API for configuring public, private and common routes (React suspense r

Pasecinic Nichita 12 Nov 11, 2022
A react component available on npm to easily link to your project on github and is made using React, TypeScript and styled-components.

fork-me-corner fork-me-corner is a react component available on npm to easily link to your project on github and is made using React, TypeScript and s

Victor Dantas 9 Jun 30, 2022
React Starter Kit — isomorphic web app boilerplate (Node.js, Express, GraphQL, React.js, Babel, PostCSS, Webpack, Browsersync)

React Starter Kit — "isomorphic" web app boilerplate React Starter Kit is an opinionated boilerplate for web development built on top of Node.js, Expr

Kriasoft 21.6k Nov 23, 2022
📋 React Hooks for forms validation (Web + React Native)

English | 繁中 | 简中 | 日本語 | 한국어 | Français | Italiano | Português | Español | Русский | Deutsch | Türkçe Features Built with performance and DX in mind

React Hook Form 31.8k Nov 23, 2022
:black_medium_small_square:React Move | Beautiful, data-driven animations for React

React-Move Beautiful, data-driven animations for React. Just 3.5kb (gzipped)! Documentation and Examples Features Animate HTML, SVG & React-Native Fin

Steve Hall 6.5k Nov 23, 2022
🎉 toastify-react-native allows you to add notifications to your react-native app (ios, android) with ease. No more nonsense!

toastify-react-native ?? toastify-react-native allows you to add notifications to your react-native app (ios, android) with ease. No more nonsense! De

Zahid Ali 29 Oct 11, 2022
A web application to search all the different countries in the world and get details about them which can include languages, currencies, population, domain e.t.c This application is built with CSS, React, Redux-Toolkit and React-Router.

A web application to search all the different countries in the world and get details about them which can include languages, currencies, population, domain e.t.c This application is built with CSS, React, Redux-Toolkit and React-Router. It also includes a theme switcher from light to dark mode.

Franklin Okolie 4 Jun 5, 2022
Finished code and notes from EFA bonus class on building a React project without create-react-app

React From Scratch Completed Code This is the completed code for the EFA bonus class on building a React project from scratch. Included are also markd

Conor Broaders 3 Oct 11, 2021
Free Open Source High Quality Dashboard based on Bootstrap 4 & React 16: http://dashboards.webkom.co/react/airframe

Airframe React High Quality Dashboard / Admin / Analytics template that works great on any smartphone, tablet or desktop. Available as Open Source as

Mustafa Nabavi 6 Jun 5, 2022
React tooltip is a React.JS Component that brings usefull UX and UI information in selected elements of your website.

React Tooltip ✅ React tooltip is a React.JS Component that brings usefull UX and UI information in elements of your website. Installation ⌨️ React Too

Marc Ramos 1 Dec 22, 2021