Skip to content

Instantly share code, notes, and snippets.

Last active Mar 20, 2022
What would you like to do?
Webpacker and I18n
$ rails new my-i8n --webpack


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


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


import I18n from 'i18n-js/index.js.erb'
$ bin/rails g controller welcome index


root 'welcome#index'


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

zedtux commented Jan 19, 2019

Brillant, just perfect !

Copy link

capjuancode commented Feb 16, 2019


Copy link

4e4c52 commented Mar 4, 2019

Thank you very much!

Copy link

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

Copy link

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.

Copy link

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


before_action :set_locale

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

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


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


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

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.

Copy link

hiveer commented Aug 13, 2019

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

Copy link

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.

Copy link

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.

Copy link

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

Copy link

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.

Copy link

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 %>";

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.

Copy link

hadees commented Nov 21, 2019

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

Copy link

dev-alihaider commented Feb 14, 2020


Copy link

fongfan999 commented May 28, 2020


Copy link

Uepsilon commented Jul 22, 2020

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

Copy link

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 ?

Copy link

t3k4y commented Nov 30, 2020

Anyone managed to combine this with jest tests?

Copy link

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

Copy link

huzaifa-malik commented Jul 20, 2021

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