A Quick Guide to Internationalization in Spring Boot

Today we want to have a quick look at how we can use and implement Internationalization (i18n) using Spring Boot and Thymeleaf templating Engine.


This quick guide will give you an introduction on how to get started with your Spring Boot internationalization process and for that we assume, that you have a working Spring application.

Setting up the project

To quickly set up our project, we will use a tool called Spring Initializr. Using this tool, we can quickly provide a list of Dependencies we need and download the bootstrapped application:

Here, we used two dependencies for our project:

  • Spring Boot Starter Web
  • Spring Boot Starter Thymeleaf

Though this tool adds these Dependencies itself, we will still provide a manual way to set up a project.

Maven Dependencies

Use any IDE to make a Maven based project. To implement our project in Spring Boot and Thymeleaf templating Engine, we will make use of Maven to manage dependencies. Here are the dependencies we will need for now:

Make sure to use the latest version of Spring Boot Starter Thymeleaf from Maven Central repository.

Using a LocaleResolver

To make our project capable of determining the locale which is currently being used, we will be using a LocaleResolver Spring bean. We use US locale by default:

The LocaleResolver comes from a very smart interface definitions which makes use of not one but four different techniques to determine current locale, this is:

  • Current session has locale information
  • Cookies being exchanged over the browser
  • The Accept-Language header being exchanged in request scope
  • A fixed value

Note that these techniques are used in the same order we mentioned them here, as more than one value can be present at any given time.

In the above bean definition, we used a SessionLocaleResolver with a default locale as US.

Locale in Request scope

As all of our requests in the project are stateless, we must know, with each incoming request that what locale should be served for this request. To accomplish this, we need to define a LocaleChangeInterceptor bean in our Application config class.

Apart from adding this bean, we also need to tell Spring to add this interceptor at request level for all incoming requests. Let’s define here our complete AppConfig class:

As stated, we add a parameter named as lang in all requests to provide information about the locale for this requests.

Messages in different languages

Now it is time to dive ourselves into language specific messages.

With Spring Boot, we can use the messages.properties file which will be used for the default locale, US in our case.

To add more locale-specific messages, we can add more files such as messages_XX.properties,where XX is the locale code, like US is for US English, SQ is for Albanian etc. You can have a look at all language codes here.

Let us define some points to be noted before we move on to defining the messages:

  • Messages are identified with keys and keys for the same message will be the same in all locale-specific files
  • When a message is retrieved, Spring Boot will look at the current set locale and will use that locale’s message file to pick up the String against that key
  • If a key is not present in current locale message file, framework will switch to the default file only for that key

With above points in mind, let us move to defining the message files now. Define following files in src/main/resources folder which is in the classpath for this application.

Here is the default messages.properties file:

Now, we create a new file called messages_fr.propertiesfor the French language with the same keys and in the same directory src/main/resources:

Now that our messages are ready, it is time to serve them to the users. To do this, we will have to define two more things in our project:

  • Controllers, which handle the request endpoints and server content like HTML pages
  • HTML pages, which are server to the user

Defining the Controllers

In the project, create a new Controller and name it as LocaleController. In this controller, we will define a single request mapping handler:

In this request my-locale is the HTML page we will define next. So, this request basically servers the HTML page we define in our project.

Defining the HTML Page

We will be using Thymeleaf Templating Engine to construct the HTML page and make use of its syntax to access locale specific keys present in our message properties file for specific locales.

Let’s show you a glimpse. In Thymeleaf, we can just do:

This will access the greeting key present in the messages.propertiesfile. This can also access the keys in messages_fr.properties file if the current set locale is found to be French, without any changes.

Apart from this, we load other locale files using Javascript as well. Let’s show you the complete HTML page we made:

Defining the Spring Boot main class

To run this application, we can define a Spring Boot main class as:

We can run this application using the command:

This will just run the current maven based project.

Accessing the application

When we run this application and visit the link http://localhost:8080/locale, we will see the following page:

When we try to select another language from the drop-down list, we move to French:

Isn’t that easy and fast?

Please note that your machines locale matter. When I ran the application, I got the English Locale page by default as that is the default language in my machine.

Exceptions with Locale messages

When using Spring boot, we can also use Global Exception Handler which provides Exception messages in user locale’s itself. This is easy to do and repetitive. We won’t be covering in this section, but we will cover a more interesting aspect.

In the file messages.properties and other locale specific files, we can define messages for Spring boot Validation API as well. Once we apply validation to our models, Spring boot will pick these messages and construct the locale message itself, based on available locales. Let’s see how to do this:

Now, whenever a validation fails for the conditions mentioned above, Spring Boot will return mentioned messages for the mentioned entity (user) and property (name, pwd etc.). In length validation cases, strings like {2}-{1} says that these will be replaced with the minimum and maximum limit mentioned during validation annotations.

Two messages, namely Exception.notFound and Exception.unexpected are global messages.

Using Phrase Spring Starter

To simplify integration of Phrase In-Context Editor into your Spring Boot application, there is an existing Phrase Spring Boot Starter which you can use to get started quickly.

Read here about how you can start using this project.


In this lesson, we integrated Internationalization process in our demo Spring Boot based application which we processed with Thymeleaf to present a layout to the user. We saw how easily we can process a user request and extract locale information from various techniques.

Spring Boot can manage any number of locales in an application flawlessly. If you need a challenge, try localization in an application with a Dynamic API like Google Translate which converts the messages at runtime. It can be slow but it is worth a try.

Internationalization is a great way to increase users on a product so there are no limits in terms of how users use your product.

However, writing code to localize your app is one task, but working with translations comes with a whole new set of challenges. Fortunately, Phrase can make your life as a developer easier! Feel free to learn more about Phrase, referring to the Getting Started guide.

If you’re interested in the topic of spring boot i18n make sure to also check out our other article which also takes a closer look at spring boot localization.

A Quick Guide to Internationalization in Spring Boot
4.5 (90.91%) 33 votes
Shubham Phrase Content Team