React-rails: I18n workflow

Created on 5 Dec 2014  路  14Comments  路  Source: reactjs/react-rails

Can anyone give me best practice or just an idea how to work with i18n components? Can be the locale passed to all the components?

Right now I'm passing locale with props and setting there I18n.locale = this.props.locale in render, before all the jsx constructions.

Most helpful comment

If anyone is coming to this from google and wanted a different way to implement this.

This is what I did and is working great. I found this solution to be the most simple.

gem "i18n-js"
yarn add i18n-js

Enabled webpacker erb

Changed server_rendering.js to server_rendering.js.erb

Changed application.js to application.js.erb

Added these two lines in both files

import I18n from "i18n-js";

I18n.translations = <%= I18n::JS.translations.to_json %>;

Now in any of my components.

    import React from "react"
    import PropTypes from "prop-types"
    import I18n from 'i18n-js';

    class HelloWorld extends React.Component {
      render () {
        return (
          <React.Fragment>
            <div>{I18n.t("greeting")}</div>
          </React.Fragment>
        );
      }
    }

   export default HelloWorld;

All 14 comments

That's a good question. I'm also wondering how to.

I am using i18njs to do this for now and then just doing I18n.t('my.key.here') to get strings out.

That's what I'm also doing currently, but it doesn't look right. Hopefully to find out better approach soon.

We're using Yahoo's react_intl and merging in its expected properties into every component manually.

Over-simplified, it looks something like this:

<%
  desired_locale_context = { locales: 'en-US', messages: { 'key': 'value', 'key2': I18n.t('rails.key2') } }
  other_props = { x: true, y: 2 }
  component_props = desired_locale_context.merge(other_props)
%>
<%= react_component 'MyComponent', component_props %>

Would be nice if there was a way to have them merged in by default.

How do you pass current locale to the nested components?

I'm passing as a normal props and setting them to the state. Isn't it better to set locale as a global state property?

The particular library I'm using passes them down automatically (or the children fetch from their parents).

For other libraries, not sure what the best practice is for this sort of state. If you're using a Flux-like architecture, a LocaleStore might make sense. I'm not sure exactly what you're describing but the docs do warn against using props to set state. https://facebook.github.io/react/tips/props-in-getInitialState-as-anti-pattern.html

We have been using i18n-js quite successfully with react-rails. It's very nice being able to reuse translations from your rails app and it works well.

We only had to do a little extra setup work to make it work properly with server-side prerendering. You can find our setup here https://gist.github.com/jhilden/44378421ad54e617b900

Thanks for the all the examples!

If anyone is coming to this from google and wanted a different way to implement this.

This is what I did and is working great. I found this solution to be the most simple.

gem "i18n-js"
yarn add i18n-js

Enabled webpacker erb

Changed server_rendering.js to server_rendering.js.erb

Changed application.js to application.js.erb

Added these two lines in both files

import I18n from "i18n-js";

I18n.translations = <%= I18n::JS.translations.to_json %>;

Now in any of my components.

    import React from "react"
    import PropTypes from "prop-types"
    import I18n from 'i18n-js';

    class HelloWorld extends React.Component {
      render () {
        return (
          <React.Fragment>
            <div>{I18n.t("greeting")}</div>
          </React.Fragment>
        );
      }
    }

   export default HelloWorld;

Hi @ericraio Nice one! This is going in the readme 馃帀 Very nice.

Hi @ericraio Nice one! This is going in the readme 馃帀 Very nice.

Awesome! One gotcha is to delete the generated comment, it has erb which causes an error after changing the file to erb.

import I18n from "i18n-js";

@ericraio import is not working for me and failing with "Cannot find module 'i18n-js'". I am using i18n-js 3.3.0 with React 16.5.2.

Hi @ericraio, thanks for the solution.
In my case all is good, but if I change default locale to something else rather than "en", it still defaults to EN. Any idea what can be wrong?

If you need default locale from rails in many components we use this approach:

// config/initializers/locale.rb

I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]

I18n.default_locale = :ru
I18n.available_locales = %i[ru en]

class I18nComponentMount < React::Rails::ComponentMount
  def react_component(name, props = {}, options = {}, &block)
    props[:i18n] = {
      locale: I18n.locale,
      default_locale: I18n.default_locale,
      available_locales: I18n.available_locales
    }

    super
  end
end

Rails.application.configure do
  config.react.view_helper_implementation = I18nComponentMount
end

After this every components has locales props and then use ericraio code.

Was this page helpful?
0 / 5 - 0 ratings