shakacode/react_on_rails

View on GitHub
docs/guides/i18n.md

Summary

Maintainability
Test Coverage
# Internationalization

You can use [Rails internationalization (i18n)](https://guides.rubyonrails.org/i18n.html) in your client code.

1. Set `config.i18n_dir` in `config/initializers/react_on_rails.rb`:

    ```ruby
    # Replace the following line by the directory containing your translation.js and default.js files.
    config.i18n_dir = Rails.root.join("PATH_TO", "YOUR_JS_I18N_FOLDER")
    ```

    If you do not want to use the YAML files from `Rails.root.join("config", "locales")` and installed gems, you can also set `config.i18n_yml_dir`:
    ```ruby
    # Replace the following line by the location of your client i18n yml files
    # Without this option, all YAML files from Rails.root.join("config", "locales") and installed gems are loaded
    config.i18n_yml_dir = Rails.root.join("PATH_TO", "YOUR_YAML_I18N_FOLDER")
    ```

2. Add that directory (or just the generated files `translations.json` and `default.json`) to your `.gitignore`.

3. The locale files must be generated before `yarn build` using `rake react_on_rails:locale`.

    For development, you should adjust your startup scripts (`Procfile`s) so that they run `bundle exec rake react_on_rails:locale` before running any webpack watch process (`yarn run build:development`). 

    If you are not using the React on Rails test helper,
    you may need to configure your CI to  run `bundle exec rake react_on_rails:locale` before any webpack process as well. 

    Note: if you try to lint before running tests, and you depend on the test helper to build your locales, linting will fail because the translations won't be built yet. 

    The fix is either to 
    1) run the rake task to build the translations before running the lint command or
    2) to run the tests first.

By default, the locales are generated as JSON, but you can also generate them as JavaScript with [`react-intl`](https://formatjs.io/docs/getting-started/installation/) support:

1. Specify the i18n output format in `config/initializers/react_on_rails.rb`:
    ```rb
    config.i18n_output_format = "js"
    ```

2. Add `react-intl` & `intl` to `client/package.json`, and remember to `bundle install && yarn install`. The minimum supported versions are:

    ```js
    "dependencies": {
      ...
      "intl": "^1.2.5",
      "react-intl": "^2.1.5",
      ...
    }
    ```

3. In React, you need to initialize `react-intl`, and set its parameters:

    ```js
    ...
    import { addLocaleData } from 'react-intl';
    import en from 'react-intl/locale-data/en';
    import de from 'react-intl/locale-data/de';
    import { translations } from 'path_to/i18n/translations';
    import { defaultLocale } from 'path_to/i18n/default';
    ...
    // Initizalize all locales for react-intl.
    addLocaleData([...en, ...de]);
    ...
    // set locale and messages for IntlProvider.
    const locale = method_to_get_current_locale() || defaultLocale;
    const messages = translations[locale];
    ...
    return (
      <IntlProvider locale={locale} key={locale} messages={messages}>
        <CommentScreen {...{ actions, data }} />
      </IntlProvider>
    )
    ```
    ```js
    // In your component.
    import { defaultMessages } from 'path_to/i18n/default';
    ...
    return (
      { formatMessage(defaultMessages.yourLocaleKeyInCamelCase) }
    )
    ```

# Notes
* See why using JSON can perform better compared to JS for large amounts of data [https://v8.dev/blog/cost-of-javascript-2019#json](https://v8.dev/blog/cost-of-javascript-2019#json).
* See [Support for Rails' i18n pluralization #1000](https://github.com/shakacode/react_on_rails/issues/1000) for a discussion of issues around pluralization.
* *Outdated:* You can refer to [react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial) and [PR #340](https://github.com/shakacode/react-webpack-rails-tutorial/pull/340), [commmited](https://github.com/shakacode/react-webpack-rails-tutorial/commit/ef369ed9d922aea5116ca7e50208169fd7831389) for a complete example.