mcpField
I
i18n-patterns

i18n-patterns

github.com/thibautbaissacDevelopment67161 installsUpdated 21w ago
Repository

About i18n-patterns

A guide to internationalization patterns for Rails 8 developers, covering translation organization, locales, formatting, and testing. It provides practical usage patterns for views, controllers, and models.

Key features

  1. 01Organize locale files by domain
  2. 02Use lazy lookups in views
  3. 03Localize dates, times, and numbers
  4. 04Configure locale switching and fallbacks
  5. 05Detect missing and unused translations

Use cases

  1. 01Add multilingual interfaces to Rails apps
  2. 02Manage model and view translations consistently
  3. 03Test translation coverage and find missing entries

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/thibautbaissac/rails_ai_agents --skill i18n-patterns

After installing, type/i18n-patternsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
locale-files.md
testing.md
usage-patterns.md

Details

From the project README

I18n Patterns for Rails 8

Overview

Rails I18n provides internationalization support:

  • Translation lookups
  • Locale management
  • Date/time/currency formatting
  • Pluralization rules
  • Lazy lookups in views

Quick Start

# config/application.rb
config.i18n.default_locale = :en
config.i18n.available_locales = [:en, :fr, :de]
config.i18n.fallbacks = true

Project Structure

config/locales/
├── en.yml                    # English defaults
├── fr.yml                    # French defaults
├── models/
│   ├── en.yml               # Model translations (EN)
│   └── fr.yml               # Model translations (FR)
├── views/
│   ├── en.yml               # View translations (EN)
│   └── fr.yml               # View translations (FR)
├── mailers/
│   ├── en.yml               # Mailer translations (EN)
│   └── fr.yml               # Mailer translations (FR)
└── components/
    ├── en.yml               # Component translations (EN)
    └── fr.yml               # Component translations (FR)

Locale File Organization

Organize locale files by domain: models/, views/, mailers/, components/.

  • Models: activerecord.models, activerecord.attributes, activerecord.errors
  • Views: nested under controller name and action (e.g. events.index.title)
  • Shared: common.actions, common.messages, common.date.formats
  • Components: components.<component_name>.<key>

See locale-files.md for complete YAML examples for models, views, shared keys, and components.

Usage Patterns

Key Principles
  • Use lazy lookup in views: t(".title") resolves to "events.index.title"
  • Use _html suffix for strings containing HTML markup
  • Use I18n.l (localize) for dates, times, and numbers — not I18n.t
  • Use I18n.t with full key path in models, services, and presenters
  • Pass dynamic values via interpolation: t(".greeting", name: user.name)
In Views
<h1><%= t(".title") %></h1>
<%= link_to t(".new_event"), new_event_path %>
<p><%= t(".welcome", name: current_user.name) %></p>
<p><%= t(".intro_html", link: link_to("here", help_path)) %></p>
In Controllers
redirect_to @event, notice: t(".success")
In Models/Presenters
I18n.t("activerecord.attributes.event/statuses.#{status}")
I18n.l(event_date, format: :long)

See usage-patterns.md for full examples including presenters, components, date/currency formatting, and pluralization.

Locale Switching

URL-Based Locale
# config/routes.rb
Rails.application.routes.draw do
  scope "(:locale)", locale: /en|fr|de/ do
    resources :events
  end
end

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def default_url_options
    { locale: I18n.locale }
  end
end
User Preference Locale
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    locale = current_user&.locale || extract_locale_from_header || I18n.default_locale
    I18n.with_locale(locale, &action)
  end

  def extract_locale_from_header
    request.env['HTTP_ACCEPT_LANGUAGE']&.scan(/^[a-z]{2}/)&.first
  end
end

Testing I18n

  • Raise on missing translations in spec/rails_helper.rb
  • Use i18n-tasks gem to detect missing and unused keys
  • Write view translation specs to assert rendered content

See testing.md for complete spec examples and i18n-tasks configuration.

Best Practices

DO
# Use nested structure matching view paths
en:
  events:
    index:
      title: Events
    show:
      title: Event Details

# Use interpolation for dynamic content
en:
  greeting: "Hello, %{name}!"

# Use _html suffix for HTML content
en:
  intro_html: "Welcome to <strong>our app</strong>"
DON'T
# Don't use flat keys
en:
  events_index_title: Events  # BAD

# Don't hardcode in views
<h1>Events</h1>  # BAD - use t(".title")

# Don't concatenate translations
t("hello") + " " + t("world")  # BAD

Checklist

  • Locale files organized by domain (models, views, etc.)
  • All user-facing text uses I18n
  • Lazy lookups in views (t(".key"))
  • Pluralization for countable items
  • Date/currency formatting localized
  • Locale switching implemented
  • i18n-tasks configured
  • Missing translation detection in tests
  • Fallbacks configured

References

  • locale-files.md — YAML locale file examples for models, views, shared keys, and components
  • usage-patterns.md — Usage examples in views, controllers, models, presenters, components, and formatting
  • testing.md — RSpec specs and i18n-tasks for translation coverage

Comments

Markdown supported