Java Properties

Java .properties files for translations

.properties files have carried Java translations since 1997: key value lines, # comments, and rules that predate widespread Unicode, which is why \uXXXX escapes exist. ResourceBundle and Spring’s MessageSource read them by naming convention, one file per locale next to the code.

This page covers the three legal separators, the escaping rules, the encoding history, and how plurals travel in a format that has none.

messages_de.properties
# Checkout screen
checkout.title=Bestellübersicht
checkout.items={count, plural, one {# Artikel} other {# Artikel}}

# Main navigation
menu.home=Startseite
menu.projects=Projekte
Key value pairs, translator comments and an ICU plural carried in a value.
Download a sample: messages_de.properties

Cheatsheet

.properties syntax in six rows

You writeWhat it means
key=value, key: value, key value All three separators are legal and all three parse. The exporter writes =.
A key on its own line Legal, and means an empty value; it imports as exactly that rather than an error.
# note or ! note The comment above a key imports as its note and is written back above it on export.
Ü Non ASCII is escaped as \uXXXX on export, so the file reads correctly under Java’s old ISO 8859-1 contract and under UTF-8 alike.
\= \: and escaped spaces in keys Separator characters inside a key survive because the exporter escapes them; a key like a=b round trips.
{count, plural, …} An ICU plural in a value is parsed into CLDR forms translators edit separately, then reassembled on export.

Key order

Sorted by name, or kept in the order keys were added. Either way it should stay stable between exports.

sorted by name
auth.signIn=Anmelden
cart.title=Warenkorb
checkout.title=Bestellübersicht
insertion order
checkout.title=Bestellübersicht
cart.title=Warenkorb
auth.signIn=Anmelden

Untranslated keys, three spellings

ResourceBundle falls back through the bundle chain when a key is missing, which is usually what you want.

exported empty
checkout.confirm=
left out
# key not exported
source fallback
checkout.confirm=Confirm purchase

Conventions

Where .properties lives

ConventionPath
Spring Boot src/main/resources/messages_de.properties
Default bundle messages.properties, the fallback locale
ResourceBundle naming basename_language_COUNTRY.properties, like messages_de_AT.properties

Typical flow: bundles live beside the code, GitHub or GitLab imports new keys on push, and translations return as a merge request per locale file.

Two plural dialects on the JVM

Legacy MessageFormat choice syntax against modern ICU.

java.text choice
files={0,choice,0#no files|1#one file|1<{0} files}
ICU plural
files={count, plural, one {# file} other {# files}}

Choice format branches on ranges, not CLDR categories, and cannot say Polish or Arabic correctly; it imports as a plain string. The ICU message carries real categories and is parsed into forms.

Plurals

Plurals in .properties

The format has no plural syntax, so ICU messages carry the forms; unlike a plain string, locamorph parses these into separate fields for translators and rebuilds the message on export.

messages_fr.properties
cart.items={count, plural, one {# article} other {# articles}}
en · two forms
cart.items={count, plural, one {# item} other {# items}}
pl · four forms
cart.items={count, plural, one {# artykuł} \
  few {# artykuły} many {# artykułów} other {# artykułu}}
ar · six forms
cart.items={count, plural, zero {لا عناصر} \
  one {عنصر واحد} two {عنصران} few {# عناصر} \
  many {# عنصرًا} other {# عنصر}}

Long values continue across lines with a trailing backslash. The categories come from CLDR: Polish four, Arabic six.

See the same plural in every format locamorph exports.

In locamorph

How locamorph handles .properties

comments

Context survives the trip

The # comment above a key imports as its note and is written back on export, so the hint a developer left for translators stays in the file.

plurals

ICU plurals in plain values

The format has no plural syntax, so plural messages travel as ICU strings that locamorph parses into editable forms and reassembles on export.

stability

Exports without surprises

Stable key order and formatting mean messages_fr.properties diffs show translation changes, not tooling churn.

Convert

Convert .properties to and from other formats

Conversion is import plus export across the shared key model.

.properties to JSON

A Java backend gaining a JavaScript front end.

  1. Import messages_*.properties; comments become notes.
  2. Dotted keys can stay flat or become a tree.
  3. Export as JSON for your JS i18n library.

.properties to XLIFF

Handing enterprise bundles to a translation agency.

  1. Import the bundles per locale.
  2. Notes ride along as XLIFF notes.
  3. Export XLIFF 1.2 for any CAT tool.

JSON to .properties

Web translations reused by the JVM services.

  1. Import the JSON locales.
  2. Trees flatten to dotted keys.
  3. Export .properties with \uXXXX escaping applied.

Bring your messages bundle

Import a .properties file on the free plan and get it back with comments intact and only the translations changed.