How to Internationalize and Translate Ruby on Rails (RoR) Applications

Learn how to add multilingual support to your Ruby on Rails application. This guide covers translating text in both Ruby and JavaScript with step-by-step instructions and GitHub commit links to a demo project.

This guide uses a demo project to show you how to:

Our demo project is a simple, user-friendly application that displays the current server time. It includes a refresh button to update the time with a single click.

Each step includes Git commit links to our demo application’s repository so you can follow along easily. In the end, app users will be able to switch between application languages, as shown below.

Our multilingual Ruby on Rails demo application with a language switcher

Rails Internationalization (i18n) and Localization (l10n) Guide

Before starting, install Ruby and Rails gems on your system.

1. Create and Set Up the Rails Application

To get started, you need to set up the base structure of your Rails project with folders for controllers, models, views, and configuration files. Then, you can move on to developing the core features of your application. For instance, in our demo project, this includes the logic to display the current server time and a button to refresh it.

  1.  Run rails new application_name. This command generates a new, empty Rails application skeleton with a default directory structure and configuration files.

Commit Reference: See commit 38b2625 in GitHub

  1. Write the actual application code. You can refer to the commit below for sample code.

Commit Reference: See commit e6ace81 in GitHub

2. Set Up Multilingual Support

Next, you need to configure the Rails application to support multiple languages. This requires you to set the default language, specify available languages, and update routes and controllers to handle language settings.

  1. Configure languages by adding the following lines to your config/application.rb file:
config.i18n.default_locale = :en
I18n.available_locales = [:en, :es, :de]

In the code above:

default_locale: The language that will be used if no other language is specified

available_locales: The list of languages that your application will support

  1. Add a scope to config/routes.rb to include a language prefix (for example,  /en, /es, /de) in your URL paths. This helps load the appropriate language based on the URL. You can place any number of routes inside the scope.
scope "/:locale" do
  get '/time', to: 'home#index', as: :time_display
end
  1. Add the following code to your ApplicationController to set the correct language:
class ApplicationController < ActionController::Base
  around_action :switch_locale

  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


switch_locale: Chooses the current language from the URL parameters or defaults to the application’s default language.

default_url_options: Ensures that all generated URLs include the current language.

Commit Reference: See commit b85bc75 in GitHub

3. Add a Language Switcher

With your application now set up to handle multiple languages, you need a way to let visitors choose their preferred language. You can do this by adding a language switcher.

In the previous step, setting default_url_options in ApplicationController ensures that all generated URLs include the current language. This allows the language switcher to maintain the chosen language across different pages.

To keep users on the same page while switching languages, use the url_for helper in the language switcher. This way, when users select a different language, they stay on the same page instead of being redirected to the homepage.

Commit Reference: See commit 127e92b in GitHub

 4. Prepare Your Code for Translation

Internationalizing your application involves preparing all text content for translation. For example, your Ruby on Rails (RoR) application may contain text content in various parts:

  • Rails views and controllers: Static and dynamic texts rendered on the server-side
  • JavaScript files: Front-end texts, messages, or events handled on the client-side (if applicable)

Preparing all types of text for translation gives users a consistent multilingual experience throughout your application. And in both cases, you need to follow the same general steps to get started:

  1. Identify all text content in your application that requires translation.
  2. Create unique keys for each text string.
  3. Add these keys and their corresponding text to your source language file in the config/locales directory.

Below, you can see the details of how to apply these steps to both your Ruby code and JavaScript code.

Part 4A: Preparing Your Ruby Code for Translation

To handle translations in Ruby on Rails, the framework provides an internationalization (I18n) library. This library includes the I18n.t function, which helps you fetch translations for different text elements in your application. When you use it inside views, it can be simplified to t. This method:

  • Accepts a key name (e.g., :hello) and returns the corresponding translation for the currently chosen language.
  • Allows you to include dynamic values in the translated string using placeholders. These dynamic values are called interpolated values, and they are passed to the t function as a second argument in the form of a hash.

To get started:

  1. Replace the text in your views with calls to the t function using translation keys:
<h1><%= t(:hello) %></h1>
<p><%= t(:current_time, time: @time) %></p>
<button id="click-me"><%= t(:refresh) %></button>
  1. Create a YAML (YAML Ain’t Markup Language) file for your source language in the config/locales directory for your translations. Rails uses YAML files, which are easy to read and write, to store translations.
  2. Add the translation keys and their corresponding default language texts to the YAML file.

Commit Reference: See commit a8ec9be in GitHub

Part 4B: Prepare All Text Content in JavaScript Files for Translation

If you have any text content in your JavaScript code, you can prepare it for translation now. The process is similar to what you did for your Ruby code. You need to add the keys and their corresponding text to your source language file in the config/locales directory. For example, for English stored in config/locales/en.yml, you might add:

en:
  confirm: "Are you sure?"

Commit Reference: See commit 49a3a45 in GitHub

You can now download your source language file (en.yml). It contains all the keys and text strings for translation into other languages.

5. Create and Add Translations

With your code ready for translation, it’s time to add translations to your Ruby on Rails application. This step involves translating your source language file into multiple languages and adding these translations to your application.

For a straightforward translation process, you can use PTC (Private Translation Cloud), a software translation tool that provides high-quality automatic translations. You only need to follow 3-steps:

  1. Upload your default language YAML file to PTC’s Free resource files translation tool
  2. Select your target languages
  3. Wait for the translation to complete and download the translated resource files

And the best part  – PTC lets you quickly translate your resource file completely for free.

Once you have the translated YAML files, store them in the config/locales directory. Each language needs its own file, named after the language code (e.g., en.yml for English, es.yml for Spanish). Ensure each file has a root element that matches the locale code.

Commit Reference: See commit 78a5fdd in GitHub

6. Make the Translations Accessible to JavaScript 

After translating your Ruby on Rails application with PTC, you received translations back in a .yml file. However, the client-side JavaScript can’t directly access these YAML files. To make these translations available in your JavaScript code, you need to convert them into JSON (JavaScript Object Notation), a format that JavaScript can read and use to display the correct texts.

For our demo project, we’ll use the i18n-js gem to handle the file conversion:

  1. Add the gem "i18n-js" to your Gemfile and run bundle install.
  2. After installation, run i18n init to generate the default configuration.
  3. Update your configuration to set the file to public/locales.json. This step prepares your app to store translations in a JSON file that JavaScript can access.

Commit Reference: See commit e16e6d4 in GitHub

  1. Finally, run the i18n export command. This command reads the translations from your YAML files and writes them into a JSON file in the public directory. 

Commit Reference: See commit 19ea088 in GitHub

Besides the i18n-js gem, you can choose between many other methods to make translations accessible to JavaScript:

  • Write a custom rake task or script to convert your YAML translation files to JSON
  • Use i18next, a powerful internationalization framework for JavaScript
  • Use Rails helpers to pass translations directly to JavaScript
  • Create an API endpoint to serve translations in JSON format
  • Embed translations directly into JavaScript files using ERB templates

Regardless of the method, the core idea remains the same: make your translation files accessible to your JavaScript code.

7. Prepare JavaScript to Use the Translations

You now have the JSON file with your translations. Next, you need to set up your JavaScript code to use these translations. To make this process simple, you can use importmap.

Import maps in Rails manage JavaScript dependencies without traditional bundlers like Webpack. This feature, introduced in Rails 7, lets you map JavaScript module names to their URLs.

Import maps help with the translation process by:

  • Including the i18n-js library, which handles translations in JavaScript
  • Managing the dependencies needed to load and use translations in your JavaScript code

To prepare your JavaScript for translations using importmap:

  1. Give the JS application access to the required libraries by adding the following to your config/importmap.rb:
pin "i18n-js", to: "https://esm.sh/i18n-js@latest/dist/import/index.js"
pin "load_locale", to: "load_locale.js"
  1. Create a file at app/javascript/load_locale.js with the following content to load the translations:
export async function loadLocale() {
  const response = await fetch('/locales.json');
  const data = await response.json();
  return data;
}

This function fetches the language data generated in the previous steps.

8.  Make JavaScript Display the Right Translations

With the translations loaded into your JavaScript code, you need to make sure your JavaScript uses the correct translations based on the language selected by the user. 

Here’s how to do it:

  1. First, tell JavaScript the current language by adding the language code to your page’s <body> tag in config/layouts/application.html.erb:
<body data-locale="<%= I18n.locale %>"> 

The data-locale attribute stores the current language code (e.g., en for English, es for Spanish). This lets your JavaScript know which language to use for translations.

  1. Next, load the i18n-js library and your translations. The i18n-js library helps manage translations in JavaScript. Import this library and load your translations in your JavaScript code:
import { I18n } from "i18n-js"
import { loadLocale } from './load_locale'
  1. When the page loads, fetch the translations and initialize i18n-js. The data-locale attribute in the <body> tag tells i18n-js which language to use:
document.addEventListener('turbo:load', async () => {
  const translations = await loadLocale();
  const i18n = new I18n(translations);
  i18n.locale = document.body.dataset['locale'];
});
  1. Finally, use the i18n.t method to get the translated strings in your JavaScript code:
if (confirm(i18n.t('confirm'))) {

Now, your JavaScript will display text in the language the user has selected, just like it does in the Rails views.

Commit Reference: See commit e158079 in GitHub

Streamlined Translations for Ruby on Rails (RoR) Apps with Full PTC Integration

By following this guide, you’ve successfully added multilingual support to your Ruby on Rails application. You learned how to:

  • Make your application’s content translatable using Rails internationalization (I18n)
  • Translate server-side texts in Ruby and client-side texts in JavaScript
  • Ensure that users can switch your application’s language smoothly

While this guide shows you how to get started with PTC’s Free resource files translation tool, you can make your translation workflow even easier by integrating PTC into your Git development workflow.

The full Git integration (coming soon) will let you:

Set-up Once and Forget About Translations

Connect PTC to your Git repository, and it will automatically handle translations for your software.

Receive Translations as MRs

As you develop, PTC monitors the resource files in your project, translates new and updated content, and sends you merge requests with the translations.

Auto-Translation for Any Branch

Whenever you work on a new feature in a branch, PTC will identify and translate new texts in that branch. You can control which branches to translate.

Better than Human Translation

PTC uses AI and machine learning to translate at a higher quality than most human translators.

Ready to reduce costs, simplify translation management, and get excellent translations?

Developer Guides

How to Internationalize and Translate Ruby on Rails (RoR) Applications

Scroll to Top