Git Product home page Git Product logo

i18next / react-i18next Goto Github PK

View Code? Open in Web Editor NEW
8.9K 47.0 1.0K 15.49 MB

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

Home Page: https://react.i18next.com

License: MIT License

JavaScript 65.71% HTML 8.23% CSS 2.62% TypeScript 10.80% Java 1.68% Objective-C 3.37% Starlark 0.52% Ruby 2.95% C++ 1.61% C 0.24% Fluent 0.41% Shell 0.02% Objective-C++ 0.44% Kotlin 1.40%
react react-native translation internationalization i18n i18next ssr

react-i18next's Introduction

react-i18next Tweet

CI Code Climate Coverage Status Quality npm

IMPORTANT:

Master Branch is the newest version using hooks (>= v10).

$ >=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 react-i18next@legacy

Documentation

The documentation is published on react.i18next.com and PR changes can be supplied here.

The general i18next documentation is published on www.i18next.com and PR changes can be supplied here.

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 development 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

Do you like to read a more complete step by step tutorial?

Here you'll find a simple tutorial on how to best use react-i18next. Some basics of i18next and some cool possibilities on how to optimize your localization workflow.

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

💻 💡 👀 📖 💬

Pedro Durek

💻 💡 👀 💬

Tiger Abrodi

💻 👀

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

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


react-i18next's People

Contributors

a-barbieri avatar adrai avatar andrewbranch avatar brumeregan avatar cellog avatar dependabot[bot] avatar greenkeeperio-bot avatar high1 avatar iamandrewluca avatar isaachinman avatar jacobmgevans avatar jamuhl avatar jmfrancois avatar juhanakristian avatar marcalexiei avatar medihack avatar merodiro avatar nicegamer7 avatar nicolechung avatar pcorpet avatar pedrodurek avatar perrin4869 avatar redbugz avatar revskill10 avatar rosskevin avatar schettino avatar tigerabrodi avatar tisoap avatar vpriem avatar wichert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-i18next's Issues

Plurals with interpolation

Hi,
how can I use plurals with interpolation? I have sometihing like that:

{
"region": "in {{component}} region",
"region_plural": "in {{component}} regions"
}

and in React comp:

const regionCount = (region) => (
<strong>
{region.regionsCount}
</strong>
);
...
const MyComp = ({
region,
t,
}) => (
<Interpolate i18nKey="ns:region" component={regionCount(region)} />
);

Is there a way to pass the count in <Iterpolate>component, maybe like this:
<Interpolate i18nKey="ns:region" component={regionCount(region)} count={10} />

to obtain:

in <strong>10</strong> regions

or

in <strong>1</strong> region

Thanx.

[question] HTML in translation strings

I'm using this package to render emails on the server with ReactDOMServer.renderToStaticMarkup, all works fine except that any html in the translation strings is escaped (presumably by React). So the email will look like:

Hello John,

<strong>Bob Smith</strong> has invited you...

instead of:

Hello John,

Bob Smith has invited you...

The translation string is something like: <strong>{{inviterFullName}}</strong> has invited you...

Are there any i18next settings to fix this or will I have to use the dangerouslySetInnerHTML attribute each time?

Should `i18next` be a peerDependency?

When building an app with react-i18next, the file i18n has a reference on the module i18next. So it means the user project should have i18next has a direct dependency.

So i18next should be listed as a peerDependency so we know exactly which version we can install

WithRef

Hello,

Can you provide a clean example about using {WithRef: true} and getWrappedInstance() to get refs inside the parent container?

Thanks.

Doesn't work with nested/deep interpolation keys

I can't use nested/deep interpolation keys because they always return undefined.

Suppose I used the Interpolate component like this:

<Interpolate i18nKey="ns:key" user={ this.props.user } />

...and the key definition is Hello, {{user.name}}!, it will not work.
I am sure I'm passing the user prop as { name: 'foo bar' }.

The problem seems to lie here; at this point, match is equal to user.name, but obviously there is no user.name prop.

If I pass a plain string in the user prop, and I update ns:key to Hello, {{user}}!, everything works.

Errors when building

Hello! I'm trying to make some modifications to react-i18next to support universal/server-side rendering. I'm using npm link to link a cloned copy of the library to my project. When I build react-i18next with npm run build, I get a warning No name was provided for external module 'react' in options.globals – guessing 'React'

When I try to build my project, I then get the error Error: Cannot find module 'react' when I import things from react-i18next.

Any advice?

i18nLoadedAt prop sent even if cached - triggering unnecessary re-renders

Initially (without caching) I was seeing 14 re-renders on a simple page which I thought was way beyond reasonable, thinking we have fundamentally coded something incorrectly.

I found i18nLoadedAt prop to be sent even if the locale is cached. I have created a Performance class that I run shouldComponentUpdate through and it logs any diff in development.

I have primed the following scenario by:

  1. loading the page (primes the i18n cache, specifically the common namespace)
  2. triggering the authentication dialog (same page)
  3. clearing the log
  4. triggering the authentication dialog (same as 2 above)

Here is the sequence:

# trigger the dialog
[Performance] [AppFrame] is dirty: state (key showAuthentication is diff)
[i18n] translator: missingKey - en common %s - $t(domain) %s - $t(domain)
[Performance] [AppFrame] is dirty: props ([i18nLoadedAt] keys are diff)
[18n] translator: missingKey - en common %s - $t(domain) %s - $t(domain)

So, the prop i18nLoadedAt is marking my component as dirty, even though:

  1. the i18n is cached and did not change
  2. my component has not changed and does not need to be re-rendered

Questions/solutions

  1. What is the intended purpose of i18nLoadedAt?
  2. Why is the i18nLoadedAt passed when the namespace in question is cached?
  3. As a hack (which I don't like), I could ignore i18nLoadedAt, but this doesn't seem like the right thing to do, and depending on 1 above, it may harm i18n non-cached locale pages and dynamic updating.

Thoughts?

Incompatible with hot module reload?

First of all, thank you for this work, 😄 it really looks a lot easier to use than react-intl which I find a little overkill for a simple app.

I have a translated view that goes like this:

import React from 'react';
import { translate } from 'react-i18next/lib';

const LoginForm = React.createClass({
    render() {
        const t = this.props.t;
        console.log(t); // <-- we should have the translation fn here
        return (
            <div>
                <h3>{ t('Sign in')}</h3>
                {/*...*/}
            </div>
        );
    }
});

export default translate(['login'])(LoginForm);

On first load and manual reload it works as advertised, displaying the translated message. The console.log(t) call returns something like function fixedT(key, options) {...}, but when I modify something on the component and thus triggering the hot reload module (Webpack), I get undefined and an Uncaught TypeError: t is not a function.

Is there any way to make react-i18next compatible with HMR?

Thanks!

Universal loading with React and Redux

Hello,

I'm trying to create an application with localization that also uses universal loading. I feel like I'm almost there but I'm having an issue with loading the user's language.

I am using 2 other modules to help me with that:
https://github.com/i18next/i18next-node-fs-backend (instead of i18next-xhr-backend in your example)
https://github.com/i18next/i18next-express-middleware

Here is what my i18n init looks like:

import i18n from 'i18next'
import Backend from 'i18next-node-fs-backend'
import { LanguageDetector } from 'i18next-express-middleware'

i18n
  .use(Backend)
  .use(LanguageDetector)
  .init({
    whitelist: ['en','en-US','fr'],
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: ['common'],
    defaultNS: 'common',

    debug: true,

    interpolation: {
      escapeValue: false // not needed for react!!
    },

    backend: {
      // path where resources get loaded from
      loadPath: 'locales/{{lng}}/{{ns}}.json',

      // path to post missing resources
      addPath: 'locales/{{lng}}/{{ns}}.missing.json',

      // jsonIndent to use when storing json files
      jsonIndent: 2
    }
  })

export default i18n

Then in my express server, I am taking i18n and using it with express so that I can detect the user's language:

import i18n from './i18n'
import { I18nextProvider } from 'react-i18next'
var i18nMiddleware = require('i18next-express-middleware')

const app = express()
app.use(i18nMiddleware.handle(i18n))

app.get('*', (req, res) => {

  console.log('language ' + req.language)
  console.log('i18n language ' + req.i18n.language)
  console.log(req.i18n.t('app.appName'))

  match({ routes, location: req.url }, (err, redirect, props) => {
      const contentHtml = ReactServer.renderToString(
        <I18nextProvider i18n={ req.i18n }>
          <Provider store={store} key="provider">
            <RouterContext {...props} />
          </Provider>
        </I18nextProvider>
      )
      res.send(layout(contentHtml, store.getState()))
  })
})

I am able to grab req.language and req.i18n.language. Also, req.i18n.t() works for the keys I pass into it. The problem is when I try and pass in req.i18n into the I18nextProvider, it throws an error saying i18n.loadNamespaces is not a function.

Do you have any other suggestions about how to use this? Or maybe there's an attribute I can add to I18nextProvider for the language to use for the user? Maybe something like this:

<I18nextProvider i18n={ i18n } language={req.language}>

Or maybe I'm going about this all wrong and you have another idea for Universally loading a React/Redux application with i18next capabilities.

Thanks for your help!

wait set to true still load the component

I'm experiencing a flickering effect when loading a component where I use wait: true.

Example to reproduce:

@translate(['common', 'app'], { wait: true })
class App extends Component {
  render() {
    const { t } = this.props
    return (
      <div className={ t('key2') }>
        { t('key1') }
        <div>{ t('common1') }</div>
      </div>
    )
  }
}

When application is loaded I see the component rendered with translation ids for few millisecs, then they are replaced by proper translations.

Isn't the wait option used for preventing this?

How to test decorated components?

Hi! I have problem with testing decorated by translate components. Just simple example:

import React, { PropTypes } from 'react';
import { translate } from 'react-i18next';
import ProductBadge from './ProductBadge';

const ProductBadgeNew = ({ product, t }) => (
  product.is_label_new
    ? <ProductBadge text={t('vendor.badges.new')} status="sold" />
    : <span />
);

export default translate(ProductBadgeNew);

First of all when we test components, we render them into document via:

import { renderIntoDocument } from 'react-addons-test-utils';
import ProductBadgeNew from '../../ProductBadgeNew';

describe('[Component] ProductBadgeNew', () => {
  it('should render without errors when there aren\'t any props', () => {
    const component = renderIntoDocument(
      <ProductBadgeNew />
    );

    expect(component).to.be.an('object');
  });
});

But we have been decorated ProductBadgeNew component with translate, and here component variable contains Translate component which decorates ProductBadgeNew. And I can't get props for my ProductBadgeNew.
I've found one interesting solution https://github.com/ghengeveld/redux/blob/a68768ff8d6a4fbe7b8f6a06a8cf9b99a54aefb0/docs/recipes/WritingTests.md#testing-decorated-react-components
The code after changes is:

import React, { PropTypes } from 'react';
import { translate } from 'react-i18next';
import ProductBadge from './ProductBadge';

export const ProductBadgeNew = ({ product, t }) => (
  product.is_label_new
    ? <ProductBadge text={t('vendor.badges.new')} status="sold" />
    : <span />
);

export default translate(ProductBadgeNew);
import { ProductBadgeNew } from '../../ProductBadgeNew';

describe('[Component] ProductBadgeNew', () => {
  it('should render without errors when there aren\'t any props', () => {
    const component = renderIntoDocument(
      <ProductBadgeNew />
    );

    expect(component).to.be.an('object');
  });
});

Now component variable contains our vanilla component without any decorations. BUT!:) Inside component we use t function which is passed via props and of course we don't have it now. How can I fix my testing workflow with your decorators? Thanks

How to use in ecmascript5 code?

Hello! If I want to use react-i18next in React components not written in ecmascript2015 how can I load translation json?

I think I need the @translate(['componentA'], { wait: true }) equivalent in ecmascript5 style.

Sample Code:

var ComponentA = React.createClass({
    render : function() {
        // I need the @translate(['componentA'], { wait: true }) equivalent in ecmascript5 javascript
        var t = reactI18next.translate;
        return <div>
            <p>{t(myNamespace:test)}</p>
        </div>
    }
});


var I18nextProvider = reactI18next.I18nextProvider;
ReactDOM.render(
    <I18nextProvider i18n={ i18n }>
        <ComponentA  />
    </I18nextProvider>,
    document.getElementById('componentA')
);

Style Parent Element

I can't find a way to properly style the parent element the text is rendered into. Can't provide a class or style property.

Warning on missing Interpolation prop

Is there a way to log a warning if an Interpolation value contains parsed values with no corresponding prop passed. It would be especially awesome if this could tie in with the i18n instance's debug setting. Basically I want to easily discover missing props

e.g.

{
  "interpolateSample": "you can interpolate {{value}} or {{component}} via interpolate component!"
}
import React from 'react';
import { translate, Interpolate } from 'react-i18next';

function TranslatableView(props) {
  const { t } = props;

  let interpolateComponent = <strong>a interpolated component</strong>;

  return (
    <div>
      <Interpolate i18nKey='ns:interpolateSample' stupid='"some string"' dumpTypo={interpolateComponent} />
    </div>
  )
}

Any thoughts on this?

Multiple namespaces not rendering on client.

I have my common.json file being pulled into Jade template files which are working fine, but I can add another namespace and have it work correctly, it keeps getting overwritten, and the resources is not added within the window.__i18n object.

Here's my i18n-server.js

import i18n from 'i18next'
import Backend from 'i18next-node-fs-backend'
import { LanguageDetector } from 'i18next-express-middleware'

i18n
  .use(Backend)
  .use(LanguageDetector)
  .init({
    whitelist: ['en'],
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: [
      'common',
      'homepage'
    ],
    defaultNS: 'common',

    debug: true,

    interpolation: {
      escapeValue: false // not needed for react!!
    },

    backend: {
      loadPath: 'locales/{{lng}}/{{ns}}.json',
      jsonIndent: 2
    }
  })

export default i18n

and the i18n-client.js

import i18n from 'i18next'

i18n
  .init({
    whitelist: ['en'],
    fallbackLng: 'en',

    // have a common namespace used around the full app
    ns: [
      'common',
      'homepage'
    ],
    defaultNS: 'common',

    interpolation: {
      escapeValue: false // not needed for react!!
    }
  })

export default i18n

I also have this within my client.js file

i18n.changeLanguage(window.__i18n.locale)
i18n.addResourceBundle(window.__i18n.locale, 'common', window.__i18n.resources, true)

ReactDOM.render(
  <I18nextProvider i18n={i18n}>
    <Router history={browserHistory}>
      { Routes }
    </Router>
  </I18nextProvider>,
  document.getElementById('app-container')
)

And this is my server.js file

  const locale = req.language
  const resources = i18n.getResourceBundle(locale, 'common')
  const i18nClient = {locale, resources}

  const i18nServer = i18n.cloneInstance()
  i18nServer.changeLanguage(locale)

And i18n is picking up my homepage.json file and it renders in the jade file (as =t('homepage:test.title') at first but then gets overwritten because it's not in the window.__i18n resources. What am I missing!

auto dangerouslySetInnerHTML

Are there easy ways not to write the dangerouslySetInnerHTML prop each time in case escapeValue property is setted up to false globally?

changeLanguage cause warning

changeLanguage cause warning and has no effect

warning.js:36
Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount.e @ warning.js:36
r @ warning.js:60
i @ ReactUpdateQueue.js:55
enqueueSetState @ ReactUpdateQueue.js:201
o.setState @ ReactComponent.js:64
onI18nChanged @ translate.js:104
(anonymous function) @ EventEmitter.js:51
emit @ EventEmitter.js:50
addResource @ ResourceStore.js:94
saveMissing @ BackendConnector.js:323
translate @ Translator.js:183
t @ i18next.js:321
fixedT @ i18next.js:313
render @ index.jsx:23
_renderValidatedComponentWithoutOwnerOrContext @ ReactCompositeComponent.js:808
_renderValidatedComponent @ ReactCompositeComponent.js:835
_updateRenderedComponent @ ReactCompositeComponent.js:759
_performComponentUpdate @ ReactCompositeComponent.js:739
updateComponent @ ReactCompositeComponent.js:658
receiveComponent @ ReactCompositeComponent.js:552
receiveComponent @ ReactReconciler.js:126
_updateRenderedComponent @ ReactCompositeComponent.js:761
_performComponentUpdate @ ReactCompositeComponent.js:739
updateComponent @ ReactCompositeComponent.js:658
performUpdateIfNecessary @ ReactCompositeComponent.js:566
performUpdateIfNecessary @ ReactReconciler.js:158
u @ ReactUpdates.js:151
perform @ Transaction.js:138
perform @ Transaction.js:138
perform @ ReactUpdates.js:90
w @ ReactUpdates.js:173
closeAll @ Transaction.js:204
perform @ Transaction.js:151
batchedUpdates @ ReactDefaultBatchingStrategy.js:63
s @ ReactUpdates.js:201
o @ ReactUpdateQueue.js:25
enqueueSetState @ ReactUpdateQueue.js:210
o.setState @ ReactComponent.js:64
onI18nChanged @ translate.js:104
(anonymous function) @ EventEmitter.js:51
emit @ EventEmitter.js:50
addResourceBundle @ ResourceStore.js:125
loaded @ BackendConnector.js:133
(anonymous function) @ BackendConnector.js:240
(anonymous function) @ BackendConnector.js:173
(anonymous function) @ index.js:104
(anonymous function) @ index.js:67
tryToString @ fs.js:449
readFileAfterClose @ fs.js:436

Date formatting relative to now

Are you interested in formatting dates relative to now with functionality similar to format.js <FormattedRelative/>?

References:

I thought I saw a discussion here previously but am unable to find it.

Thoughts?

Access currently active language

Is there a way to make the decorator expose the language which is currently enabled? I'm looking for a nice way to display this in my application's menu bar.

Is this something you'd be open to adding if it isn't currently supported?

404 on resources loading

Hi,

I try to integrate react-i18next in my react project but the translations init fail with a 404 :

image

Here is my project structure & i18N configuration :

image

My index.jsx


import React from "react";
import ReactDOM from "react-dom";
import { I18nextProvider } from 'react-i18next';
import i18n from './utils/i18n'; // initialized i18next instance


import 'bootstrap/less/bootstrap'
import App from "./containers/App";

ReactDOM.render(
    <I18nextProvider i18n={ i18n }><App /></I18nextProvider>,
    document.getElementById("app")

);

The component render by App :

import React from 'react';
import { translate } from 'react-i18next';

function Component({t}) {
  return <p>{t('usingDefaultNS', { /* options t options */ })}</p>
}

export default translate()(Component);

I don't find what i do wrong ... any ideas ?

How to reload(re-render) react component after changeLanguage?

Hello.

I used static table maker and render when first initialization (componentDidMount).

First time to translate (Initialization), It doesn't matter.

but If I change lang after init, my static table doesn't translate like table header title or something.

Does react-i18next have re-rendering component function?

How can I do?

missing deps

there are 3 missing deps for this module.

i18next
i18next-xhr-backend
i18next-browser-languagedetector

html tags in i18next translation files in react are always getting escaped

Hi Jan,

I stumbled upon http://stackoverflow.com/questions/39836369/html-tags-in-i18next-translation-files-in-react/ and see the same problem.

I played with different configuration:

translations:

EmptyState.activity.paragraph.2=Commit to the repository <em>{0}</em> or run the pipeline manually.

jsx:

 const inner = t('EmptyState.activity.paragraph.2', {
        0: repoName,
        interpolation: {
            escapeValue: false,
            escape: false,
        }
    });

I added the interpolation (I found both attributes in the web but I think only the first one is actually used) to see whether that makes a different but I have in the init already:

        interpolation: {
            escapeValue: false,
        }

Any hints?

How to change language after initialization

Hi.

I'm trying to change language after init, but it seems to be quite tricky.

Our language is encoded in the url /lang/foo/bar, and i've made custom detector to pick that up (That works).
The detector only seems to run on initialization, so i've tried to add a listener to the history api location change (i use react-router with browser history), and the event gets fired okay, and my i18n.changeLanguage also seems to work, but the new language is not reflected in the I18nextProvider

  • Is it not possible to change language after init?
  • If so, it would be lovely with an example on how to properly hook up the I18nextProvider to make this work.

Thanks in advance.. :)

Cannot read property 'loadNamespaces' of undefined

Hi, I run into this issue:

Uncaught TypeError: Cannot read property 'loadNamespaces' of undefined
i18next::backendConnector: loaded namespace common for language en-US Object {appName: "app name sample", interpolateSample: "you can interplate {{value}} or {{component}} via interpolate component!"}
i18next: languageChanged en-US
i18next: initialized
Object {debug: true, ns: Array[1], defaultNS: "common", fallbackLng: Array[1], fallbackNS: false…}

app.js is the following:

class App extends Component {

    ...

    render () {
        return (
            <Router history={hashHistory}>
                <Route path='/' component={Homepage}>
                    <Route path='signin' component={Signin} />
                    <Route path='signup' component={Signup} />
                    ...
                    ...
                </Route>
            </Router>
        );
    }
}


const RootedApp = root(App, store);
render(<I18nextProvider i18n={i18n}><RootedApp /></I18nextProvider >, document.getElementById('app'));

i18n.js

import i18n from 'i18next';
import XHR from 'i18next-xhr-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

i18n
.use(XHR)
.use(LanguageDetector)
.init({
    fallbackLng: 'en',

    ns: ['common'],
    defaultNS: 'common',

    debug: true,

    interpolation: {
        escapeValue: false
    }
});

export default i18n;

Then, in my Home.js:

import React, {Component} from 'react';
import { translate } from 'react-i18next';

@translate(['view', 'nav'])
class Home extends Component {

    render () {
        const { t } = this.props;

        return (
            <div'>
                <h1>{t('common:appName')}</h1>
                {this.props.children}
            </div>
        );
    }
};

Anyway, i18next seems to be correctly loaded. What's the problem?

Thanks

Universal rendering issue on ^1.5.0

Hi,

On react-i18next >= 1.5.0, universal rendering is broken.
Error: Invariant Violation: React DOM tree root should always have a node reference.

Related to this issue react issue, this line might be the cause.

A rerender occur on server-side because of a setState inside the componentWillMount hook

My server side setup :

  match({ routes, location}, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message)
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
      loadNamespaces(Object.assign({}, renderProps, {i18n}))
      .then(() => {
        const isNotFound = renderProps.routes.find((route) => {
          return route.status === 404
        })
        const locale = req.language
        const locales = res.locals.locales
        const component = (
            <I18nextProvider i18n={req.i18n}>
              <RouterContext
                {...renderProps}
              />
            </I18nextProvider>
        )

        res.status(isNotFound ? 404 :  200).send('<!doctype html>\n' +
          renderToStaticMarkup(<Html assets={webpack_isomorphic_tools.assets()}
                                     component={component} />))
      })
    } else {
      res.status(404).send('Not found')
    }
  })
 // html.js
  render()
  {
    const { assets, component} = this.props
    // throw error below
    const content = component ? ReactDOM.renderToString(component) : ''
}

Do you have any clue?

Thanks

Is there any way to return an entire namespace via the translate function?

I have a datepicker component, which takes an object for localisation:

{
  "lang": {
    "placeholder": "Select date",
    "rangePlaceholder": [
      "Start date",
      "End date"
    ],
    "today": "Today",
    "now": "Now",
    "backToToday": "Back to today",
    "ok": "Ok",
    "clear": "Clear",
    "month": "Month",
    "year": "Year",
    "timeSelect": "Select time",
    "dateSelect": "Select date",
    "monthSelect": "Choose a month",
    "yearSelect": "Choose a year",
    "decadeSelect": "Choose a decade",
    "yearFormat": "YYYY",
    "dateFormat": "M/D/YYYY",
    "dayFormat": "D",
    "dateTimeFormat": "M/D/YYYY HH:mm:ss",
    "monthFormat": "MMMM",
    "monthBeforeYear": true,
    "previousMonth": "Previous month (PageUp)",
    "nextMonth": "Next month (PageDown)",
    "previousYear": "Last year (Control + left)",
    "nextYear": "Next year (Control + right)",
    "previousDecade": "Last decade",
    "nextDecade": "Next decade",
    "previousCentury": "Last century",
    "nextCentury": "Next century"
  },
  "timePickerLocale": {
    "placeholder": "Select time"
  }
}

I have this in my translations as datepicker, however accessing t('datepicker') returns undefined, presumably because it's meant to return a string, not an object.

I can access what I need via: i18n.getResourceBundle(i18n.languages[0]).datepicker, but I'm wondering if there is any way to do the same via the translate function itself, as this solution feels a bit hacky.

Doesn't work with Babel 5.8.3 and React 1.4.5

I get this error in console and Uncaught Error: Cannot find module 'react'
webpack also throw error
WARNING in .//react-i18next/bin/index.js
Critical dependencies:
1:414-421 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to
get better results.
@ ./
/react-i18next/bin/index.js 1:414-421

Problem with redux-forms

I am having problems trying to integrate it with redux-forms.

This is my code:

const LoginTranslated = translate('bulma')(Login);

export default reduxForm({
  form: 'login',
  fields: ['email', 'password'],
  validate,
  getFormState: state => state.bulma.reduxForm,
}, mapStateToProps)(LoginTranslated);

and I am getting this error:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the Translate[Login] component.

It doesn't work doing it the other way around either:

const LoginForms = reduxForm({
  form: 'login',
  fields: ['email', 'password'],
  validate,
  getFormState: state => state.bulma.reduxForm,
}, mapStateToProps)(Login);

export default translate('bulma')(LoginForms);

Any ideas?

Getting missingKey undefined

I'm facing an issue when trying to test the example project provided here: https://github.com/i18next/react-i18next/tree/master/example

In the console, I'm getting the following errors:

"i18next::translator: missingKey undefined common appName appName"
"i18next::translator: missingKey undefined nav linkDE linkDE"
" i18next::translator: missingKey undefined nav linkEN linkEN"
" i18next::translator: missingKey undefined nav link1 link1"

I think render is occuring before init. Do you have an idea how to solve it?

Thanks,

Test container with multiple components translated

I am trying to test a container that has multiple components inside. When I mount the container all the nested containers will be mounted but I have an error:

TypeError: Cannot read property 'getFixedT' of undefined

Some of my components are exporting with the translation decorator:

export const TextAreaCounterComponent = TextAreaCounter;

export default translate(['defaultNamespace'])(TextAreaCounterComponent);

How can I test this containers?

  const mockT = () => 'Hello';
  const middlewares = [];
  const mockStore = configureStore(middlewares);

  const initialState = {
    login: {
      loggedIn: true,
    },
    app: {
      isLoading: false,
      popupIsOpen: false,
      tabSelected: 0
    }
  };
  const store = mockStore(initialState);

  const wrapper = mount(
    <Provider store={store}>
      <Partner t={mockT} />
    </Provider>
  );

  it.only('should mount partner page container', () => {
    expect(wrapper.find('.wrap').length).toBe(1);
  });

Doesn't work with `react-google-maps`

When rendering react-google-maps component in a class that is wrapped with react-i18next, it throws the following error.

translate.js:115 Uncaught TypeError: Cannot read property 'getFixedT' of undefined

The conflict occurs in the component managed by that react-google-maps. For some reason it doesn't pass on the i18n property, so accessing this.i18n. getFixedT() throws an error.

TypeError: Cannot read property 'translator' of undefined

Hello friends.

I found this error in the server log and the application does not work. What can it be?

TypeError: Cannot read property 'translator' of undefined at t (/home/myapp/app/node_modules/i18next/dist/commonjs/i18next.js:315:16) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:1192:482) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:1598:129) at res (/home/myapp/app/node_modules/jade/lib/index.js:219:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:380:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:370:21) at View.exports.__express [as engine] (/home/myapp/app/node_modules/jade/lib/index.js:417:11) at View.render (/home/myapp/app/node_modules/express/lib/view.js:126:8) at tryRender (/home/myapp/app/node_modules/express/lib/application.js:639:10) at EventEmitter.render (/home/myapp/app/node_modules/express/lib/application.js:591:3) TypeError: Cannot read property 'translator' of undefined at t (/home/myapp/app/node_modules/i18next/dist/commonjs/i18next.js:315:16) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:1192:482) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:1598:129) at res (/home/myapp/app/node_modules/jade/lib/index.js:219:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:380:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:370:21) at View.exports.__express [as engine] (/home/myapp/app/node_modules/jade/lib/index.js:417:11) at View.render (/home/myapp/app/node_modules/express/lib/view.js:126:8) at tryRender (/home/myapp/app/node_modules/express/lib/application.js:639:10) at EventEmitter.render (/home/myapp/app/node_modules/express/lib/application.js:591:3) TypeError: Cannot read property 'translator' of undefined at t (/home/myapp/app/node_modules/i18next/dist/commonjs/i18next.js:315:16) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:266:1647) at eval (eval at <anonymous> (/home/myapp/app/node_modules/jade/lib/index.js:218:8), <anonymous>:272:23) at res (/home/myapp/app/node_modules/jade/lib/index.js:219:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:380:38) at Object.exports.renderFile (/home/myapp/app/node_modules/jade/lib/index.js:370:21) at View.exports.__express [as engine] (/home/myapp/app/node_modules/jade/lib/index.js:417:11) at View.render (/home/myapp/app/node_modules/express/lib/view.js:126:8) at tryRender (/home/myapp/app/node_modules/express/lib/application.js:639:10) at EventEmitter.render (/home/myapp/app/node_modules/express/lib/application.js:591:3)

errors using Interpolate

I'm trying to use the Interpolate component, but I'm running into errors:

Error: Invariant Violation: findComponentRoot(..., .0.0.0.0.0.1.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.

No idea where to start debugging, I'm using the code as described in the readme.

No unit tests ?

Hi,

I'm currently evaluate this react module and I can't find any tests inside it.

Do you plan to add any QA to it ?

  • write tests
  • add test coverage
  • add travis CI

I18nextProvider breaks server side rendering.

Hi! After setup i18n on server side rendering i see, thats everything from first component wrapped in translate not render.

Server side code:
`const store = configureStore();

const initialView = renderToString(
  <I18nextProvider i18n={req.i18n}>
    <Provider store={store}>
      <RouterContext {...renderProps} />
    </Provider>
  </I18nextProvider>
);

const finalState = store.getState();

const html = renderHtml(initialView, finalState, {locale: 'en', resources: req.i18n.getResourceBundle('en', 'common')});`

And i get something like:
<html>... <body><header><div>static</div><!-- react empty: 1 --></header> <!--react empty:2 --></body></html>

I check dictionaries, it loaded. (i use express middleware)

How to use react-i18next translate with generated component by jQuery DOM.

Sorry, My last question looks very terrible.

I used Table generator by jQuery. It located component's function. not render function.

In this generator, I have to define first row's haad (table head).

like this :

colModel: [
                    {
                        label: t('settings.user-id'),
                        name: 'userId',
                        width: 100
                    },
                   {
                        label: t('settings.user-nm'),
                        name: 'userNm',
                        width: 100
                    }
                ]

The problem is not shown in first page initialization.

The problem comes when I I change language using this i18next.changeLanguage(event.target.value); function.

It is remain initialized language. Other component is OK, but just defined items in table row didn't changed. I think, i18next can't catch look like data-reactid=".0.0.3.1.0.7.1.1.0.0

How do you think about?

SaveMissing causes errors with setState()

i18n.js configuration:

i18n
  .use(XHR)
  .use(LanguageDetector)
  .init({
    wait: true,
    bindI18n: 'languageChanged loaded',
    fallbackLng: 'cz',
    saveMissing: true,

    backend: {
      crossDomain: true,
      loadPath: endpoint.TRANSLATION + '/{{lng}}',
      addPath: endpoint.TRANSLATION
    }
  })

saveMissing: true causes Warning: setState(...): Cannot update during an existing state transition (such as within render or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to componentWillMount error.

When setting to false, errors stop.

The problem occurs on line 113 of react-i18next/dist/commonjs/translate.js when this.setState({ i18nLoadedAt: new Date() }); is executed. (Commenting that line stops the errors, but breaks language changing.)

Versions:

"i18next": "^3.5.1",
"i18next-browser-languagedetector": "^0.3.0",
"i18next-xhr-backend": "^1.2.1",
"react-i18next": "^1.11.0",

Support raw HTML in translation values

Say we have the next translation resource:

{foo: "<b>Bar!</b>"}

Then <div><Interpolate i18nKey='foo' /></div> will result in the next output:
<div>&lt;b&gt;Bar!&lt;/b&gt;</div> , while I expect to get this: <div><b>Bar!</b></div> , so a raw HTML in translation strings should not be escaped.

Is this an intended behavior, or is a bug?

I guess replacing this line with something like
child = React.createElement(parent, {dangerouslySetInnerHTML: {__html: match}}); will work this out.

Inject components into translation

I'm wondering if I'm are the only one with this kind of needs.
On the current application I'm working on, it might be useful if we could use a component as value. For example:

render() {
 return I18n.t('key', { value: <Link onclick={() => } />}
}

In this example, Link returns a link with predefined set of props that we use everywhere.
@jamuhl , does something like this makes sense to add? If so, how would you suggest to do it?

Export static properties of the Component

Imagine I have a the following class with static properties.

class Presets extends React.Component {
    static timeToAbbr() {
        console.log('timeToAbbr');
    };
}

export default translate(['presets'])(Presets);

From outside of the component I cannot call Presets. timeToAbbr() as a class function.

If I exported the class directly without wrapping it into Translate component as follows, it can successfully call the static function.

export default Presets;

Set component prop?

Any pointers on when I need something like below?

I'm having trouble with the async aspect on i18next when I need to set a component prop.
i18next is sometimes not yet ready before I set this prop.
Or is this outside the scope of this repo?

i18n.js

import i18n from 'i18next/lib';
import XHR from 'i18next-xhr-backend/lib';

i18n
    .use(XHR)
    .init({
        debug: true,
        lang: 'nl',
        fallbackLng: 'nl',
        defaultNS: 'translation',
        interpolation: {
            escapeValue: false
        }
  });

export default i18n;

form.js

import i18next from './i18n.js'; // instance

export default React.createClass({
    render() {
        <Input
            name="name"
            placeholder={i18next.t('placeholder')}
        />
    };
});

Question on tooling

Can you recommend a tool and configuration for using react-18next with a translation key extractor? I'm unsure of the best way.

Thanks

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.