Hot questions for Using Spree in locale


I'm trying to internationalize a Rails/Spree app using spree's own spree_i18n gem, but I can't get it to work.

I made a minimal app which recreates the problem here.

To cut a long story short, I have the following code in my ApplicationController:

before_action :set_locale

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
  puts I18n.locale

And code in my view which should be translated (<%= t("whatever") %>). But no matter what I do, the text is always output in English.

With some additional code for debugging, I can see that once set_locale is called but while execution is still within the controller, the locale is correct (e.g. if I visit the url /?locale=es, then the puts statement in the above controller code outputs es).

But by the time execution has reached the view, the locale has somehow been reset to en. (E.g. adding <% raise I18n.locale.to_s %> within the view raises "en" as an error message.)

I've opened an issue on Spree's Github because as far as I can tell I've followed their instructions exactly and it's still not working, but I may still be missing something. Why isn't the locale getting set properly?

(Note: I should add that the Spree.t doesn't work either, not just t.)

EDIT: If you look at the comment on my Github issue, you'll see that I got it working. However, I'm 99% sure that my solution is a hack and there's a better method I should be using. Bounty goes to whoever can tell me what I'm dong wrong.


Spree I18n gives a way to set default language: on config/application.rb with config.i18n.default_locale = :es

And the possibility of setting the languages to be changed. Perhaps on config/initializers/spree_i18n.rb

SpreeI18n::Config.available_locales = [:en, :es, :de] 
SpreeI18n::Config.supported_locales = [:en, :es, :de] 

After that, you can remove set_locale on ApplicationController, because it has no effect.

With this at place, it works like a charm.


I change the message of error because I want to be sure that it works:

<%= product_description(@product) rescue Spree.t(:product_has_no_description) +
' ' + Spree.t(:action) %>

And I add a new product without description. Running the server at localhost

In english I see: "This product has no description Action"

In spanish I see: "Este producto no tiene descripción Acción"

In deutsch I see: "Produkt hat keine Beschreibung Aktion"

Exactly the expected.

You can see the source with changes at github


I am trying to customize Spree_i18n frontend nav-bar locale and am having some issues changing it from a select_tag to a link_to. I am trying to make it appear with only two locales selections EN/CN. What would the best solution for this be?


load = function() {
  return $('#locale-select select').change(function() {
    return $.ajax({
      type: 'POST',
      url: $(this).data('href'),
      data: {
        locale: $(this).val()
    }).done(function() {
      return window.location.reload();


<li id="locale-select" data-hook>
  <%= form_tag set_locale_path, class: 'navbar-form' do %>
    <div class="form-group">
      <label for="locale" class="sr-only"><%= t(:'i18n.language') %></label>
      <%= select_tag(:locale, options_for_select(supported_locales_options, I18n.locale), class: 'form-control', data: { href: set_locale_path }) %>
      <noscript><%= submit_tag %></noscript>
  <% end %>


My custom variant

<%= link_to 'en', spree.set_locale_path(switch_to_locale: :en), method: :post %>


my SpreeCommerce Shop (2.4, spree_i18n 2.4 ist installed) does not detect the browser language preferences. Just the default language will be displayed.

Language configurations are set on the SpreeCommerce admin page ( Supported Locales and Available Locales).

Any advice would be great.


You need to add some logic to your application to set the Rails.locale to one of the locales which you support based upon the request Accept-Language passed in.

This functionality isn't supported directly by spree-i18n, but designed to be implemented by your application.