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.
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.
Run rails new application_name. This command generates a new, empty Rails application skeleton with a default directory structure and configuration files.
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.
Configure languages by adding the following lines to your config/application.rb file:
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
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
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.
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.
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:
Identify all text content in your application that requires translation.
Create unique keys for each text string.
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:
Replace the text in your views with calls to the t function using translation keys:
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.
Add the translation keys and their corresponding default language texts to the YAML file.
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:
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:
Upload your default language YAML file to PTC’s Free resource files translation tool
Select your target languages
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.
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:
Add the gem "i18n-js" to your Gemfile and run bundle install.
After installation, run i18n init to generate the default configuration.
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.
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.
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:
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"
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.
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:
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.
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'
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:
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?