Skip to content

Instantly share code, notes, and snippets.

@bazzel
Last active Jul 20, 2021
Embed
What would you like to do?
Webpacker and I18n
$ rails new my-i8n --webpack

Gemfile

gem 'i18n-js'
$ bundle --binstubs
$ yarn add i18n-js
$ bin/rails webpacker:install:erb

app/javascript/i18n-js/index.js.erb

import I18n from "i18n-js"
I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
export default I18n

app/javascript/packs/application.js

import I18n from 'i18n-js/index.js.erb'
console.log(I18n.t('hello'))
$ bin/rails g controller welcome index

config/routes.rb

root 'welcome#index'

app/views/layouts/application.html.erb

<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
$ bin/rails s
@zedtux

This comment has been minimized.

Copy link

@zedtux zedtux commented Jan 19, 2019

Brillant, just perfect !

@capjuancode

This comment has been minimized.

Copy link

@capjuancode capjuancode commented Feb 16, 2019

🥇

@4e4c52

This comment has been minimized.

Copy link

@4e4c52 4e4c52 commented Mar 4, 2019

Thank you very much!

@joseglego

This comment has been minimized.

Copy link

@joseglego joseglego commented Apr 9, 2019

Hello! @bazzel It works well for me. BUT I have a doubt, why

bundle --binstubs

Why not use the binstub of the specific gem which required it?
Or why it doesn't work with just bundle

@bazzel

This comment has been minimized.

Copy link
Owner Author

@bazzel bazzel commented Jul 12, 2019

Hi @joseglego,

Thanks for the feedback. I'm not sure where I read this, but to my understanding --binstubs creates a /bin directory so commands can be executed as bin/rails s instead of rails s or bundle exec rails s.

@balakirevs

This comment has been minimized.

Copy link

@balakirevs balakirevs commented Aug 3, 2019

Hi @bazzel,
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?

i have added

application_controller.rb

before_action :set_locale

  def default_url_options(options = {})
    { locale: I18n.locale }.merge options
  end

  def set_locale
    default_locale = Rails.configuration.i18n.default_locale.to_s
    begin
      if params[:locale].to_s.in? MyI8n::LOCALES
        params_locale = params[:locale].to_s
      end
      if request.env['HTTP_ACCEPT_LANGUAGE'].present?
        candidate_locale = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
        if candidate_locale.to_s.in? MyI8n::LOCALES
          request_locale = candidate_locale.to_s
        end
      end
      @locale = params_locale || session[:locale].presence || request_locale || default_locale
      I18n.locale = @locale.to_s
      session[:locale] = I18n.locale
    rescue
      I18n.locale = default_locale
      session[:locale] = I18n.locale
    end
  end

config/application.rb

module MyI8n
  LOCALES = %w[de fr en].freeze

  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    config.i18n.available_locales = MyI8n::LOCALES
    config.i18n.default_locale = 'en'
    config.i18n.fallbacks = (['en'] + MyI8n::LOCALES).uniq
  end
end

routes.rb

scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
    root 'welcome#index'
  end

and also created fr & de yml files.
The result i have always hello world in english in application.js though if i add in the view

<%= I18n.locale %>

and switch locale it shows the correct one.

@hiveer

This comment has been minimized.

Copy link

@hiveer hiveer commented Aug 13, 2019

I have a question here, since webpacker support ERB, why not just use I18n from Rails directly?

@alxckn

This comment has been minimized.

Copy link

@alxckn alxckn commented Aug 25, 2019

I have a question here, since webpacker support ERB, why not just use I18n from Rails directly?

@hiveer ERB asset files will be evaluated at compile time, not upon each request, so the only locale you'll be able to see is the one set as default.

@OtherCroissant

This comment has been minimized.

Copy link

@OtherCroissant OtherCroissant commented Aug 27, 2019

How can I make sure webpacker invalidates the cached translations and regenerate the i18n-js/index.js.erb?
When I change the translations that are used in my JS, the translations are not updated in I18n.translations.

@strickland84

This comment has been minimized.

Copy link

@strickland84 strickland84 commented Sep 10, 2019

Ditto @CUnknown, @bazzel is there a way to auto-update these without reloading the server when making changes in dev? Thanks for the gist, very helpful

@bazzel

This comment has been minimized.

Copy link
Owner Author

@bazzel bazzel commented Sep 10, 2019

@CUnknown @strickland84 don't have an answer for that, I'm afraid. To be honest: I didn't get that far when writing this up, so I think this needs some more investigation.

@kfiltschew

This comment has been minimized.

Copy link

@kfiltschew kfiltschew commented Sep 18, 2019

If you want to use the rails set locale, you can take this solution:

app/layouts/applcation.html.erb - save default locale in a global variable (LOCALE) you can access everywhere.

...
<script type="text/javascript">
  var LOCALE = "<%= I18n.locale %>";
</script>
...

app/javascript/i18n-js/index.js.erb - use the global variable LOCALE

import I18n from "i18n-js"

I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
I18n.locale = LOCALE;

export default I18n;

Other points should match the example.

@hadees

This comment has been minimized.

Copy link

@hadees hadees commented Nov 21, 2019

can you do this without using erb? I'm having other problems with erb and webpacker.

@dev-alihaider

This comment has been minimized.

Copy link

@dev-alihaider dev-alihaider commented Feb 14, 2020

Great

@fongfan999

This comment has been minimized.

Copy link

@fongfan999 fongfan999 commented May 28, 2020

Awesome

@Uepsilon

This comment has been minimized.

Copy link

@Uepsilon Uepsilon commented Jul 22, 2020

👍 thanks man, that saved me at least a few hours.

@nathan-ch

This comment has been minimized.

Copy link

@nathan-ch nathan-ch commented Sep 29, 2020

Hi, we are changing our front end to use only React as a Single Page Application inside the Rails app with Webpacker.

I wonder if i can use i18n-js to translate html generated from React.
With this piece of code, i am able to receive translations in React code but the js import of I18n only gives defaultLocale, not the currentLocale.
I can write code to get currentLocal from localStorage or cookies easily but is there a way to handle url without rewriting the detection functions in js ?

@t3k4y

This comment has been minimized.

Copy link

@t3k4y t3k4y commented Nov 30, 2020

Anyone managed to combine this with jest tests?

@m-andreas

This comment has been minimized.

Copy link

@m-andreas m-andreas commented Jul 19, 2021

Thanks for the Hint @kfiltschew! So you can just use:

import I18n from "i18n-js"
I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
I18n.locale = "<%= I18n.locale %>";
export default I18n

in i18n-js/index.js.erb

@huzaifa-malik

This comment has been minimized.

Copy link

@huzaifa-malik huzaifa-malik commented Jul 20, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment