Generic Top

I just announced the new Spring Boot 2 material, coming in REST With Spring:


1. Overview

In this quick tutorial, we’re going to take a look at how we can add internationalization to a Spring Boot application.

2. Maven Dependencies

For development, we need the following dependency:


The latest version of spring-boot-starter-thymeleaf can be downloaded from Maven Central.

3. LocaleResolver

In order for our application to be able to determine which locale is currently being used, we need to add a LocaleResolver bean:

public LocaleResolver localeResolver() {
    SessionLocaleResolver slr = new SessionLocaleResolver();
    return slr;

The LocaleResolver interface has implementations that determine the current locale based on the session, cookies, the Accept-Language header, or a fixed value.

In our example, we have used the session based resolver SessionLocaleResolver and set a default locale with value US.

4. LocaleChangeInterceptor

Next, we need to add an interceptor bean that will switch to a new locale based on the value of the lang parameter appended to a request:

public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
    return lci;

In order to take effect, this bean needs to be added to the application’s interceptor registry.

To achieve this, our @Configuration class has to implement the WebMvcConfigurer interface and override the addInterceptors() method:

public void addInterceptors(InterceptorRegistry registry) {

5. Defining the Message Sources

By default, a Spring Boot application will look for message files containing internationalization keys and values in the src/main/resources folder.

The file for the default locale will have the name, and files for each locale will be named, where XX is the locale code.

The keys for the values that will be localized have to be the same in every file, with values appropriate to the language they correspond to.

If a key does not exist in a certain requested locale, then the application will fall back to the default locale value.

Let’s define a default message file for the English language called

greeting=Hello! Welcome to our website!
lang.change=Change the language

Next, let’s create a file called for the French language with the same keys:

greeting=Bonjour! Bienvenue sur notre site!
lang.change=Changez la langue

6. Controller and HTML Page

Let’s create a controller mapping that will return a simple HTML page called international.html that we want to see in two different languages:

public class PageController {

    public String getInternationalPage() {
        return "international";

Since we are using thymeleaf to display the HTML page, the locale-specific values will be accessed using the keys with the syntax #{key}:

<h1 th:text="#{greeting}"></h1>

If using JSP files, the syntax is:

<h1><spring:message code="greeting" text="default"/></h1>

If we want to access the page with the two different locales we have to add the parameter lang to the URL in the form: /international?lang=fr

If no lang parameter is present on the URL, the application will use the default locale, in our case US locale.

Let’s add a drop-down to our HTML page with the two locales whose names are also localized in our properties files:

<span th:text="#{lang.change}"></span>:
<select id="locales">
    <option value=""></option>
    <option value="en" th:text="#{lang.eng}"></option>
    <option value="fr" th:text="#{}"></option>

Then we can add a jQuery script that will call the /international URL with the respective lang parameter depending on which drop-down option is selected:

<script src="">
<script type="text/javascript">
$(document).ready(function() {
    $("#locales").change(function () {
        var selectedOption = $('#locales').val();
        if (selectedOption != ''){
            window.location.replace('international?lang=' + selectedOption);

7. Running the Application

In order to initialize our application, we have to add the main class annotated with @SpringBootApplication:

public class InternationalizationApp {
    public static void main(String[] args) {, args);

Depending on the selected locale, we will view the page in either English or French when running the application.

Let’s see the English version:

screen shot in English
And now let’s see the French version:
screen shot in French

8. Conclusion

In this tutorial, we have shown how we can use the support for internationalization in a Spring Boot application.

The full source code for the example can be found over on GitHub.

Generic bottom

I just announced the new Spring Boot 2 material, coming in REST With Spring:


newest oldest most voted
Notify of
Slava Semushin
Slava Semushin

> window.location.replace(‘international?lang=’ + selectedOption);

Looks like this is too coupled with a page URL. How it’s supposed to work if I have 30+ pages?

Also using jQuery for such a trivial things looks superfluous. Perhaps, something like this would work too.

Loredana Crusoveanu
Loredana Crusoveanu

The focus here was on the Spring Boot portion, with the jQuery sample being used for exemplification. We’re, of course, not relegated to any specific client side technology or implementation. If we wanted the language to change for all pages of an application, we could have a global variable that retains the locale code and an interceptor to add the lang parameter to every request, but that depends on what front end framework we are using. If you don’t like the parameter approach, there is also the possibility of creating a custom LocaleChangeInterceptor in Spring that could determine the locale,… Read more »

Adheli Tavares
Adheli Tavares

I’m getting a ??home.welcome?? on my page. Do you know how to solve this?

Grzegorz Piwowarek
Grzegorz Piwowarek

Adheli, is this a problem with your project or with our codebase?

Adheli Tavares
Adheli Tavares

I did solve it, but I don’t remember how, as I’m not next to my computer. If I’m not wrong, it was a problem with the setBasename.

Loredana Crusoveanu
Loredana Crusoveanu

Hey Adheli.

I see you placed your messages file in a different location than src/main/resources. Spring Boot automatically picks up the file from that location only. If you place it somewhere else, then yes, you would have to manually define the resource bundle.

Adheli Tavares
Adheli Tavares

they are in src/main/resources/locale/messages now. I put them first in resources and it didn’t work.

Adheli Tavares
Adheli Tavares

I get quite confused with some @EnableSomething because they always turn something off from Spring. If you could make an article about those annotations, it’d awesome!

Adheli Tavares
Adheli Tavares

I had to add this overriding on a @Configuration class.

public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
return messageSource;