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.
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, visitors need a way to 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, 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.
For a streamlined translation process, use PTC. This translation tool provides high-quality AI-powered translations and integrates seamlessly into your development workflow.
How translation works with PTC:
Set Up Your Project and Connect Your Repository
Start by setting up your project in PTC and linking it to your repository. PTC automatically detects your resource files in the config/locales directory.
Select Target Languages
Choose the languages you want to translate into during the project setup.
Get Translations Delivered via Merge Requests
PTC translates your YAML file using its advanced AI and sends the translated files directly to your repository as a merge request. Each language will have its own YAML file, named after the language code (e.g. es.yml for Spanish).
The translated YAML files are stored in the config/locales directory. Each file includes a root element matching the locale code to maintain compatibility with Ruby on Rails’ I18n system.
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:
Adding multilingual support to your Ruby on Rails application is a critical step toward reaching a global audience. By following this guide, you’ve:
Made your app’s content translatable using Rails internationalization (I18n)
Learned how to translate server-side texts in Ruby and client-side texts in JavaScript
Set up a smooth process for users to switch languages
PTC makes the translation process easy. With advanced AI-powered translations, direct integration with your development workflow, and automatic translation updates, PTC handles the heavy lifting so you can focus on building your app.
Ready to reduce costs, simplify translation management, and get excellent translations?