Components Language select

Petal Pro is the full SaaS app this is built for

Auth, billing, admin, and Claude Code integration included. One purchase, unlimited projects.

Language select

A drop down to pick your language. Free in petal_components 4.10 - graduated from Petal Pro.

The flag dropdown for a header or footer. Items are plain links carrying ?locale= (&-joined when the path already has a query) - the conventional Phoenix contract, working on live and dead views alike. The current language is marked with aria-current and a check.

heex
<div class="flex justify-center py-4">
<.language_select
current_locale="en"
current_path="#"
language_options={[
%{locale: "en", flag: "🇬🇧", label: "English"},
%{locale: "fr", flag: "🇫🇷", label: "Français"},
%{locale: "de", flag: "🇩🇪", label: "Deutsch"},
%{locale: "es", flag: "🇪🇸", label: "Español"}
]}
/>
</div>
Text triggers, flags optional

A flag is a country, not a language - Portuguese isn't only 🇵🇹. variant="code" puts the locale code on the trigger, variant="label" the language name, and options that omit :flag render as clean text rows.

heex
<div class="flex flex-wrap items-center justify-center gap-10 py-4">
<.language_select
current_locale="en"
current_path="#"
variant="code"
language_options={[
%{locale: "en", label: "English"},
%{locale: "pt", label: "Português"},
%{locale: "de", label: "Deutsch"}
]}
/>
<.language_select
current_locale="pt"
current_path="#"
variant="label"
show_chevron={false}
language_options={[
%{locale: "en", flag: "🇬🇧", label: "English"},
%{locale: "pt", flag: "🇵🇹", label: "Português"},
%{locale: "de", flag: "🇩🇪", label: "Deutsch"}
]}
/>
</div>
Graceful when unconfigured

An unknown current_locale falls back to a language glyph instead of raising - a half-configured app renders a working menu, not a crash.

heex
<div class="flex justify-center py-4">
<.language_select
current_locale="xx"
current_path="#"
language_options={[
%{locale: "en", flag: "🇬🇧", label: "English"},
%{locale: "fr", flag: "🇫🇷", label: "Français"}
]}
/>
</div>

When a user selects a dropdown item, it will redirect to the same page but with the locale parameter on the end, eg: /?locale=en (&-joined when the path already carries a query). A plug or on_mount hook reads the param and calls Gettext.put_locale/2 - Petal Pro ships one that also remembers the choice in a cookie.

Properties
Attribute Type Default Description
class any nil extra classes for the dropdown container
current_locale* string the active locale, e.g. from Gettext.get_locale/1
current_path string "" the path the locale links return to; the locale query param is appended
label string "Change language" accessible name for the trigger
language_options* list one map per language: %{locale: "en", flag: "🇬🇧", label: "English"} - :flag is optional
placement string "left"
one of: "left", "right"
rest global
show_chevron boolean true hide for the cleanest text triggers - the flag or code stands alone
variant string "flag" what the trigger shows: the current flag, the locale code (EN), or the language name
one of: "flag", "code", "label"