Can't find i18n in Phoenix docs

Maybe I am doing something wrong but I can’t find anything about i18n in Phoenix docs.

Also, I have noticed, that for some reason the lang tag is hardcoded in the default root template as “en”.

Also, I can’t find anything about locales, default_locale, fallback_locale as in other frameworks like Laravel.

I do see gettext folder.

Why is there gettext folder and locales are completely missing?

Also, is there a tutorial on how to setup a Phoenix app with a typical urls like / and /de/ and /ua/ ?

I have checked LiveView help and there, also, is nothing about making the website multilingual.

1 Like

Phoenix uses the gettext library to do i18n. You can find its documentation here: Gettext — gettext v0.20.0


Like @LostKobrakai said, most of the docs you’ll need are under the Gettext library.

I found this tutorial that looks useful; it demonstrates doing the URL-locale thing:


In addition, it’s also possible to setup locale in live socket with this kind of code in assets/js/app.js

let liveSocket = new LiveSocket("/live", Socket, {
  params: {
    _csrf_token: csrfToken,
    locale: Intl.NumberFormat().resolvedOptions().locale,
    timezone_offset: -(new Date().getTimezoneOffset() / 60),

So that liveview is aware of client locale

And for Liveview, more docs can be found here: Using Gettext for internationalization — Phoenix LiveView v0.18.3

I keep seeing the jargon “backend module” all the time. What does that mean? What is backend in this module context? Admin area? Protected area?

Hmm, thanks, will take a look. Hopefully, it will work with LiveView.

How do you make

<html lang="en">

dynamic and not hardcoded in root template using LiveView?

In Laravel it is done like this:

<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

How do you achieve this in Phoenix?

And again, why isn’t it already there in the first place? Together with the locales and default locale? For example, in Laravel it is set in config/app.php file, namely locale, default_locale, fallback_locale and faker_locale. I mean at least the locale could be put in config/config.exs somewhere by default ;(

As it is now, it seems half baked meaning you got gettext but you are missing locales and local is hardcoded in the root template file.

I followed it and the URL part doesn’t work with LiveView. I see the English version all the time. I thought it is working when I tried /nl first time and it showed the NL content, however then I manually tried /en and English showed. Then I tried again /nl but English was shown there:

Shouldn’t this part in root.html.heex:

<!DOCTYPE html>
<html lang="en">

be something like

<!DOCTYPE html>
<html lang="<%= my_current_locale() %>">

or something?

Another problem if I have this in routes:

  scope "/:locale", MyWeb do
    pipe_through :browser

    live "/", HomeLive

/ doesn’t work anymore, although it should work as the default language . /nl and /en work but only English is shown.


http://localhost:4000/   <-- this should show the default language but doesn't
http://localhost:4000/en   <-- this works 
http://localhost:4000/nl   <-- this works but showed the NL content correctly only first time, after refresh English

That’s only for logging it seems. For guests it has no impact and LiveView doesn’t show gettext correctly at least for me.

I have found this library now Phoenix Localized Routes - Localized/multilingual routes in Phoenix but the things you have to change in the example_web.ex file are missing in Phoenix 1.7 . Also, the project seems to be temporarily or permanently down, at least for me:

As for the manipulation of the language tag in the static part you can use GitHub - BartOtten/phoenix_live_head: HTML Head element manipulation for Phoenix Live View

Thanks. How would it be in this case of this code in root.html.heex (lib/example_web/components/layouts/root.html.heex):

<html lang="en">


<html data-dynamic-lang="{current_language}">

Is the data-dynamic- the magic part that will do it?

And then it will be rendered in the root.html.heex as:

<html lang="es"> or <html lang="de"> depending on the route?

Will it work for all live routes and both first html render and then the websocket connection?

One more question, if you don’t mind.

Do you think the changes to make Phoenix Localized Routes compatible with Phoenix 1.7 are too complex and time consuming or you will figure it out in a couple of weeks?

I am asking because I can somehow postpone the language switching part of the app for a month or two or so, but if it will take longer e.g. 6 months I will probably need to use Laravel with GitHub - codezero-be/laravel-localized-routes: A convenient way to set up and use localized routes in a Laravel app. because the translated url parts based on the language selected is too important for me.

In template (using “en” as default / fallback)

<html data-dynamic-lang="{dynamic}" lang="en">

There is no magic detection of locale. You should get that value by other means (for example custom assignment from Localized Routes)

In the Live View:

|> Phx.Live.Head.push("html", :set, "lang", assigns.loc.locale)

Localized Routes can already be used with Phoenix 1.7 when using the former default method of using the route helpers. It only lacks support at this moment for the new verified routes.

As changing helpers to verified routes might be just as much work as changing verified routes to localized verified routes, I’d say: use the Phoenix route helpers as we all have done in the previous decade.

ps. working on that 1.7 example.

1 Like

Turns out, too much has changed to be 100% compatible. Modules have been renamed and so on. Will work on the 1.7 compatible version soon.