Skip to content

(hilla) documentation for Internationalization (i18n) #4278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: latest
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions articles/hilla/guides/i18n.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
title: Internationalization (i18n)
page-title: Adding Internationalization (i18n) to Hilla Applications

Check warning on line 3 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.HeadingCase] 'Internationalization (i18n)' should be in title case. Raw Output: {"message": "[Vaadin.HeadingCase] 'Internationalization (i18n)' should be in title case.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 3, "column": 20}}}, "severity": "WARNING"}
description: Enable multilingual support in Hilla applications by configuring and using the Hilla i18n system.
meta-description: Guide to setting up and using internationalization (i18n) with Hilla applications.
order: 140
---

= [since:com.vaadin:[email protected]]#Internationalization (i18n) Support#

Check warning on line 9 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.HeadingCase] 'Internationalization (i18n) Support' should be in title case. Raw Output: {"message": "[Vaadin.HeadingCase] 'Internationalization (i18n) Support' should be in title case.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 9, "column": 35}}}, "severity": "WARNING"}

You can easily add internationalization (i18n) support to your Hilla applications using the `@vaadin/hilla-react-i18n` package. This guide walks you through setting up and using the feature effectively to create multilingual user interfaces.

[NOTE]
====
Internationalization in Hilla is still under active development and is not yet suitable for production. Therefore, to use it in Vaadin projects, you'll need to enable explicitly the experimental feature in Copilot, or add `com.vaadin.experimental.hillaI18n=true` to the [filename]`src/main/resources/vaadin-featureflags.properties` file.
====

== Add and Configure `i18n`

First, import the `i18n` module and call the `configure` method during your application setup or in your main view initialization.

[source,typescript]
----
import { effect } from '@vaadin/hilla-react-signals';
import { i18n } from '@vaadin/hilla-react-i18n';

effect(() => {
i18n.configure();
});
----

=== Behavior Details

By default, the system uses the browser's language (`navigator.language`). If a user has previously selected a language, it will be remembered in a cookie. You can also explicitly configure the language during setup:

Check warning on line 34 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Will] Avoid using 'will'. Raw Output: {"message": "[Vaadin.Will] Avoid using 'will'.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 34, "column": 125}}}, "severity": "WARNING"}

[source,typescript]
----
i18n.configure({ language: 'de-DE' });
----

Configuration marks the system as initialized, allowing your UI to react accordingly.

== Create and Place Translation Files

Translation files must be placed in the following file:

----
src/main/resources/vaadin-i18n/translations.properties
----

These files follow the standard Java `.properties` file format, where each line contains a key-value pair separated by an equals sign (`=`). Keys represent the translation identifiers, and values are the corresponding translations.

Example of a `translations.properties` file for English:

----
addresses.form.city.label=City
addresses.form.street.label=Street
----

To add support for other languages, create additional `.properties` files with the language code appended to the filename. For example, to add German translations, create a file named `translations_de.properties`:

----
addresses.form.city.label=Stadt
addresses.form.street.label=Straße
----

The system automatically selects the appropriate file based on the active language. Language codes are structured to represent the language and optional regional variations, such as `en` for English or `en-US` for American English.

If a translation is missing in the most specific file (e.g., `translations_de_DE.properties`), the system gracefully falls back to a less specific file (e.g., `translations_de.properties`). If no match is found, it defaults to the base file (`translations.properties`), ensuring the application remains functional even when translations are incomplete.

== Use the `translate` Function

The `translate` function retrieves translated strings based on the active language.

[source,tsx]
----
import { translate } from '@vaadin/hilla-react-i18n';

return <div>{translate('addresses.form.city.label')}</div>;
----

If a translation is missing, the key will be shown as-is.

Check warning on line 82 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Will] Avoid using 'will'. Raw Output: {"message": "[Vaadin.Will] Avoid using 'will'.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 82, "column": 38}}}, "severity": "WARNING"}

== React Integration

i18n is deeply integrated into the reactive programming model of Hilla. Components automatically update when the language changes. Signal-based reactivity (`useSignalEffect`, `useComputed`) works seamlessly.

Example using computed signals:

[source,tsx]
----
import { useComputed } from '@vaadin/hilla-react-signals';
import { translate } from '@vaadin/hilla-react-i18n';

function OrderSummary({ itemCount }: { itemCount: number }) {
const orderMessage = useComputed(() => {
if (itemCount === 0) {
return translate('order.empty');
} else {
return translate('order.details', { count: itemCount });
}
});

return <div>{orderMessage.value}</div>;
}
----

You can also show placeholders before i18n is initialized:

[source,tsx]
----
{i18n.initialized.value ? <ActualContent /> : <LoadingSpinner />}
----

== Dynamically Changing the Language

You can switch the language at runtime to adapt to user preferences.

[source,typescript]
----
i18n.setLanguage('de-DE');
----

== ICU Message Format Support

Check warning on line 124 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Abbr] 'ICU' has no definition. Raw Output: {"message": "[Vaadin.Abbr] 'ICU' has no definition.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 124, "column": 4}}}, "severity": "WARNING"}

Hilla's i18n system supports the ICU Message Format, enabling advanced translation scenarios like pluralization, selection, and number/date formatting.

Check warning on line 126 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Abbr] 'ICU' has no definition. Raw Output: {"message": "[Vaadin.Abbr] 'ICU' has no definition.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 126, "column": 34}}}, "severity": "WARNING"}

Example in `translations.properties`:

[source,properties]
----
messages.count=You have {count, plural, one {# message} other {# messages}}.
----

Usage example:

[source,typescript]
----
translate('messages.count', { count: 5 }); // Output: "You have 5 messages."
----

Supported ICU features include:

Check warning on line 142 in articles/hilla/guides/i18n.adoc

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [Vaadin.Abbr] 'ICU' has no definition. Raw Output: {"message": "[Vaadin.Abbr] 'ICU' has no definition.", "location": {"path": "articles/hilla/guides/i18n.adoc", "range": {"start": {"line": 142, "column": 11}}}, "severity": "WARNING"}

- dynamic number and date formatting;
- plural forms;
- gender and value-based selections;
- escaping special characters.

== Hot Module Replacement (HMR) in Development

During development, translation files update automatically through Hot Module Replacement (HMR). No manual reload is needed: when translations change, they are automatically fetched and applied.

With these tools, building responsive and adaptable multilingual applications with Hilla becomes intuitive and efficient.