Localizely logo
  • Home
  • Getting started
  • How it works
  • Pricing
  • FAQ
Sign up

I18n questions · Localization files

How do I use variables in Rails i18n YAML files? 

Write the placeholder as %{name} in the translation and pass name: to t. The value is substituted at lookup time, so the YAML file never contains Ruby code or string concatenation.

en:
  greeting: "Hello, %{name}!"
  inbox:
    one: "You have %{count} message"
    other: "You have %{count} messages"
<%= t("greeting", name: current_user.first_name) %>
<%= t("inbox", count: @messages.size) %>

Rules worth knowing, all from the Rails i18n guide:

  • Every placeholder in the string must be passed, otherwise I18n::MissingInterpolationArgument is raised.
  • The option names of translate are reserved and cannot be placeholder names: scope, default, separator, format, object, resolve, cascade, fallback, raise, throw, exception_handler, deep_interpolation and skip_interpolation (the i18n gem also reserves its internal fallback_in_progress and fallback_original_locale). A translation containing %{scope} raises I18n::ReservedInterpolationKey.
  • count is not reserved but special. When the key resolves to a hash, count picks the plural form and is still available as %{count}. The built-in rule for :en is zero if the hash has that key and the count is 0, one for 1, other for everything else; if the key does not resolve to a hash, I18n::InvalidPluralizationData is raised. For languages with more forms (few, many) add the rails-i18n gem, which supplies the locale-specific rules; the forms each language needs are listed at language plural rules.
  • Placeholders are not reordered by the code, so translators can move %{name} anywhere in the sentence, and %{name} can appear more than once.

A percent sign on its own is not special, so "50% off" needs no escaping. Only %{...} and %<...> are placeholders (the second form takes a format spec, for example %<price>.2f). To print the text %{name} literally, write %%{name}: the interpolation pattern of the i18n gem turns %% into a single % and leaves {name} as plain text.

Keys that end in _html (or are named html) return an HTML-safe string, and interpolated values are escaped unless they are already HTML-safe:

en:
  welcome_html: "<b>Welcome, %{username}!</b>"

With t("welcome_html", username: "<script>") the tag in the username is escaped while the <b> from the translation is kept.

One YAML detail trips people up: a value that starts with % has to be quoted ("%{count} items"), because % is an indicator character in YAML. The other characters that need quoting are covered in How do I write line breaks and special characters in YAML localization files?, and the file layout at Rails YAML file.

Published Oct 9, 2026 · Markdown version

Related localization file questions:

Supported file formats:

See the localization file formats Localizely supports
Localizely logo
About
Free tools
Boring stuff
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Compare
Newsletter
Copyrights 2026 © Localizely