Receber por email
← Voltar para o catálogo

spree-i18n

Localize a Spree application — the `spree_i18n` gem with 60+ locale packs, the v5.4+ Translations Center for product/CMS content (CSV import/export), Rails i18n basics applied to Spree (translation files, locale switching, pluralization, interpolation), per-Market locale routing in the headless storefront, RTL languages, and translating extensions. Use when localizing a Spree store, adding a new l

34estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add OrcaQubits/agentic-commerce-skills-plugins

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/spree-i18n/svg)](https://www.skillteca.com.br/skills/spree-i18n)

Alerta por categoria

Receba novas skills de Escrita e Conteúdo toda segunda

1 email curto, só com as skills novas de Escrita e Conteúdo. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Spree i18n & Localization

Before writing code

Fetch live docs:

  1. Fetch https://spreecommerce.org/docs/developer/core-concepts/translations for the v5+ translation model.
  2. Fetch https://github.com/spree-contrib/spree_i18n (README) for the current locale-pack inventory.
  3. Cross-reference https://guides.rubyonrails.org/i18n.html for Rails-side i18n basics.
  4. Check the v5.4 announcement for Translations Center features.
  5. Verify which locales ship vs. which require the spree_i18n gem on top of spree.

Conceptual Architecture

Two Layers of Localization

| Layer | What it translates | |-------|--------------------| | spree_i18n gem | UI labels — admin chrome, checkout strings, error messages, attribute names | | Translations Center (v5.4+) | Per-record content — product names, descriptions, taxon names, CMS page bodies |

Both layers cooperate — spree_i18n localizes the UI shell; Translations Center localizes the data inside the shell.

spree_i18n Inventory

Provides translation YAML files for 60+ locales (verify against the live gem). Add to Gemfile:

gem 'spree_i18n'

Locales include English, Spanish, French, German, Italian, Portuguese (BR + PT), Dutch, Polish, Czech, Russian, Ukrainian, Japanese, Korean, Chinese (Simplified + Traditional), Arabic, Hebrew, Turkish, Hindi, and many more.

Setting Available and Default Locales

# config/application.rb
config.i18n.available_locales = %i[en de fr es it]
config.i18n.default_locale = :en
config.i18n.fallbacks = true

Per-Store locale (v5+):

Spree::Store.default.update!(default_locale: 'de', supported_locales: 'en,de,fr')

Locale Switching in Requests

In the storefront (Next.js), locale is part of the URL: /de/products/.... In Rails admin, locale comes from current_user.locale or a ?locale=de param.

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_locale

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

  def default_url_options
    { locale: I18n.locale }
  end
end

Translations Center (v5.4+)

For content stored in DB (product names, descriptions, taxon labels, CMS pages, blog posts), Spree v5.4+ provides the Translations Center — an admin UI + CSV import/export to manage per-record translations.

The underlying mechanism is Mobility (or similar — verify the gem Spree uses currently) which stores translations in JSON columns or sidecar tables:

product.name        # current locale
I18n.with_locale(:de) { product.name }  # German
product.name_translations  # { 'en' => 'Tee', 'de' => 'T-Shirt' }

CSV Import/Export Flow

  1. Admin → Translations → Export → choose models + locales → download CSV
  2. Send to translators (or feed to a translation service)
  3. Re-import → Spree updates per-record translations
  4. Background job (Sidekiq) processes large imports

Per-Market Locale Routing (Headless)

The Next.js storefront's market routing handles locale:

/us/en/products/classic-tee     -> US market, English
/de/de/produkte/classic-tee     -> DE market, German
/eu/fr/produits/classic-tee     -> EU market, French

Routes are localizable — the storefront generates language-specific slugs.

RTL Languages

Arabic, Hebrew, Persian. Tailwind 4 has built-in RTL support via dir="rtl" on the <html> element. The Spree storefront includes RTL CSS variants — verify on the current release.

<html lang="ar" dir="rtl">

Date / Currency / Number Formatting

Use Rails' built-in helpers:

I18n.l(order.created_at, format: :short)   # localized date
number_to_currency(product.price, locale: I18n.locale)

Translating an Extension

# config/locales/en.yml
en:
  spree_my_extension:
    products:
      featured_label: "Featured"
      out_of_stock: "Currently unavailable"
<%= t('spree_my_extension.products.featured_label') %>

For other locales, ship parallel YAML files (de.yml, fr.yml).

Implementation Guidance

Adding a New Locale to an Existing Store

bundle add spree_i18n
# config/application.rb
config.i18n.available_locales = config.i18n.available_locales + [:ja]
# In admin or via console
Spree::Store.default.update!(supported_locales: 'en,ja')

Then translate per-record content via Translations Center.

Translating Validation Messages

Spree's validation messages live in spree_i18n's locale files. Override for a specific message:

# config/locales/en.yml
en:
  errors:
    messages:
      blank: "is required"
  activerecord:
    errors:
      models:
        spree/order:
          attributes:
            email:
              blank: "We need your email to contact you"

Localizing Email Templates

# app/mailers/spree/order_mailer.rb (or decorator)
def confirm_email(order, resend = false)
  @order = order
  I18n.with_locale(order.user&.locale || order.store.default_locale) do
    mail(to: @order.email, subject: t('.subject', store: @order.store.name))
  end
end

Translating Product Names Programmatically

product.name_translations = { 'en' => 'Classic Tee', 'de' => 'Klassisches T-Shirt' }
product.save!

(Verify the exact column / method name for translation storage in your version.)

URL Slug Translations

For SEO, taxons and products can have per-locale slugs:

taxon.slug_translations  # { 'en' => 'shirts', 'de' => 'hemden' }

The storefront's router resolves /de/hemden/... to the right taxon.

Pluralization

en:
  cart:
    items:
      one: "1 item"
      other: "%{count} items"
<%= t('cart.items', count: @cart.line_items.sum(:quantity)) %>

For locales with complex plural rules (Polish, Russian, Arabic), Rails i18n + the cldr-rules backend handles them — verify the gem.

Testing Translations

RSpec.describe 'Checkout', type: :system do
  context 'in German' do
    before { I18n.locale = :de }
    after { I18n.locale = :en }

    it 'shows German UI' do
      visit '/de/cart'
      expect(page).to have_content('Warenkorb')
    end
  end
end

Common Pitfalls

  • Forgetting to add the locale to available_locales — Rails falls back to default silently.
  • Hardcoding strings in extension views — extracts run finds untranslated ones; lint with i18n-tasks.
  • Per-store locales not enforced — Store#supported_locales is descriptive; you still need URL routing to enforce.
  • CSV imports overwriting recent edits — back up before bulk import.
  • RTL CSS bleeding into LTR sections — test mixed-direction layouts.
  • Date formats inconsistent — define :short, :long, :default formats per locale.
  • Slugs not translated — fine for English-only sites, breaks SEO for multi-language.
  • Translation Center disabled — older Spree versions don't have it; users hit a 404.

Always cross-reference spree_i18n for locale-pack coverage and the v5.4 Translations Center docs for per-record translation patterns.

Compartilhar X LinkedIn