Downloads locale ETF files from the Localize CDN and stores them in the configured locale cache directory.
This task is intended to be run at build time (e.g. in a Dockerfile or CI pipeline) so that all required locales are available in the cache before the application starts. This avoids the need for runtime downloads in production.
Inflection data for the same locales is downloaded in the same
step (via mix localize.download_inflection), so one command
provisions both. Locales the inflection project does not support
are skipped.
Usage
mix localize.download_localesDownloads the configured :supported_locales. When
:supported_locales is not configured (meaning all CLDR
locales are supported), prompts for confirmation before
downloading.
mix localize.download_locales en fr de jaDownloads the specified locales.
mix localize.download_locales --allDownloads all CLDR locales without prompting.
mix localize.download_locales --force--force does two things: (1) when :supported_locales is not
configured, it downloads all locales without prompting (useful in
CI/Docker where there is no interactive terminal); and (2) it
re-downloads every requested locale even if a current copy already
exists in the configured cache directory, bypassing the
"already current" skip.
Output directory
Files are written to the directory returned by
Localize.Locale.Provider.locale_cache_dir/0, which defaults
to Application.app_dir(:localize, "priv/localize/locales").
Three configuration forms are recognised (see
Localize.Locale.Provider.locale_cache_dir/0):
# 1. Recommended. The Elixir/Phoenix/Ecto/Gettext :otp_app
# convention. Resolved as
# `Application.app_dir(:my_app, "priv/localize/locales")` at
# every read, so it computes the right path in mix tasks
# (`_build/<env>/lib/my_app/priv/...`) and releases
# (`/path/to/release/lib/my_app-X.Y.Z/priv/...`).
config :localize, otp_app: :my_app
# 2. :otp_app + a *relative* :locale_cache_dir. The relative
# path is resolved against the app's runtime root, i.e.
# `Application.app_dir(:my_app, "priv/i18n/cache")`. Use
# this when you want app-anchored resolution but a custom
# subpath.
config :localize,
otp_app: :my_app,
locale_cache_dir: "priv/i18n/cache"
# 3. Absolute literal path. Use for fully custom locations (a
# shared mount, a fixed system path). :otp_app is ignored
# in this form.
config :localize, locale_cache_dir: "/var/lib/localize/locales"A relative :locale_cache_dir without an :otp_app anchor is
refused and raises Localize.LocaleCacheDirError at app start —
with no anchor, a relative path resolves against the BEAM's
current working directory, which differs between mix tasks, mix test, and a release, so one value cannot be correct in all phases.
Skip behaviour
A locale is reported (current) and skipped only when a
version-matching copy already exists in the configured cache
directory — the same directory the task writes to. The bundled
fallback directory inside the :localize dependency
(Application.app_dir(:localize, …)) is deliberately not
consulted for this decision, so a copy shipped with the dependency
never prevents the task from populating your configured directory.
Use --force to re-download regardless of the current copy.
Compile-time configuration
The task only loads compile-time configuration (config/config.exs and any
imported env-specific files) and never evaluates config/runtime.exs. This
makes it safe to run inside "build-only" environments (such as Docker images)
where production-only environment variables are deliberately not available.
The task itself reads only :localize's own compile-time config.
Examples
Pre-populate the cache for a Docker build:
# Dockerfile
RUN mix localize.download_localesDownload specific locales for testing:
mix localize.download_locales en de ja zhDownload everything in a non-interactive environment:
mix localize.download_locales --force