Skip to navigation
Phoenix framework - the preferred way to handle internationalization
12.06.26
In the Phoenix framework, the preferred way to handle internationalization (i18n) and localization (l10n) is by using the **`gettext`** library. It is the industry standard for Elixir applications and is included by default when you generate a new Phoenix project. Here is the breakdown of the preferred workflow and best practices: ### 1. The Core: `gettext` Phoenix uses `gettext` to manage translations. You will find a `lib/my_app_web/gettext.ex` file in your project, which defines the backend for your translations. ### 2. The Workflow The standard workflow for managing locales in Phoenix follows these steps: #### A. Marking strings for translation Instead of hardcoding strings in your templates or code, you wrap them in Gettext macros: * **Templates (`.heex`):** Use the `gettext` function. ```elixir
<%= gettext("Welcome to my website") %>
``` * **Elixir Code:** Use the `gettext` macro from your project's Gettext module. ```elixir import MyAppWeb.Gettext # ... flash(:info, gettext("Profile updated successfully!")) ``` #### B. Extracting strings Once you have marked your strings, you run a mix task to extract them into `.pot` (Portable Object Template) files: ```bash mix gettext.extract ``` This scans your code for all `gettext` calls and updates the files in `priv/gettext/default.pot`. #### C. Translating For each language you want to support (e.g., French), you create a directory structure: `priv/gettext/fr/LC_MESSAGES/default.po`. You then populate these files with the translations: ```po msgid "Welcome to my website" msgstr "Bienvenue sur mon site web" ``` ### 3. Handling Locales in the Request Lifecycle To make your app "locale-aware," you need to set the locale for the current user session. This is typically done via a **Plug**. 1. **Create a Plug:** Create a `SetLocale` plug that checks the URL (e.g., `example.com/fr/dashboard`), a cookie, or the `Accept-Language` header. 2. **Set the Locale:** Use `Gettext.put_locale/1` inside that plug. ```elixir def call(conn, _opts) do locale = get_locale_from_params(conn) || "en" Gettext.put_locale(MyAppWeb.Gettext, locale) conn end ``` 3. **Plug it in:** Add this plug to your `router.ex` inside the `:browser` pipeline. ### 4. Best Practices * **Use `dgettext` for domains:** If your app is large, don't put all strings in `default.po`. Use `dgettext("errors", "...")` to split translations into different files (e.g., `errors.po`, `emails.po`). * **Use `ngettext` for plurals:** Always use `ngettext` when dealing with quantities to handle different pluralization rules across languages. ```elixir ngettext("You have one message", "You have %{count} messages", count) ``` * **Keep keys as English:** Use the English sentence as the `msgid`. This makes the code readable even if the translation files aren't updated yet. * **Use `cldr` for formatting:** While `gettext` handles text, it does not handle date/time or currency formatting. For those, use the [ex_cldr](https://github.com/elixir-cldr/cldr) library, which is the standard companion to `gettext` for full localization. ### Summary 1. **`gettext`** is the tool for text. 2. **`mix gettext.extract`** is your best friend for maintenance. 3. **Plugs** are the preferred way to switch locales per request. 4. **`ex_cldr`** is the preferred way to handle localized numbers, dates, and currencies.
https://www.phoenixframework.org/
Reply
Anonymous
Information Epoch 1785958893
Save trees.
Home
Notebook
Contact us