Vaadin 14, set Locale

I am developing a Vaadin 14 + Spring Boot 2 application with i18n-suppport.

In Vaadin 14, the locale is automatically determined by the Accept-Language header provided by the browser.
In my application, I cannot rely on this. Many users have an English version of the browser, but still wants the application to use Swedish locale.

I would like to offer my users to select a locale, apply it and store it as a cookie. Pretty much exaclty the way you typically use the
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/i18n/CookieLocaleResolver.html
in Spring.

I have seen some older (pre Vaadin 14) examples when you could use the CookieLocaleResolver, but it seems that that is not the case anymore.

What would be the best way to override the default locale resolving to also take a cookie into consideration?

The locale is configured based on the request locale when a session is created. Furthermore, each newly created UI instance gets its locale from the session it belongs to. Updating the session local after it has been initialized will also update the locale for any UI that is already associated with that session.

In both cases, the locale is initialized before a corresponding initialization event is fired. You can thus register either a session init listener or a UI init listener where you reset the session or UI locale based on your own logic. The session init event has immediate access to a request object from which you can read cookies. If you use the UI init event instead, then you’d have to use VaadinRequest.getCurrent() instead.

Both listener types are most easily registered from a global VaadinServiceInitListener. Vaadin’s Spring integration automatically looks for beans that implement that listener interface, so it’s usually enough to annotate your implementation with @Component.

Because I was interested in this as well and Leif explaining where this can be done, I have implemented this just now and it indeed works.
Here is the code that will make Vaadin use the Locale from a cookie if such a cookie exists. (if it does not exist, Vaadin will decide which Locale to use just like before)

@Component
public class ApplicationServiceInitListener implements VaadinServiceInitListener {
    @Override
    public void serviceInit(ServiceInitEvent event) {
        event.getSource().addSessionInitListener(sessionInitEvent -> {
            final VaadinRequest request = sessionInitEvent.getRequest();
            final VaadinSession session = sessionInitEvent.getSession();

			// TODO: change the cookie name to the name that you actually use ;)
            Cookie localeCookie = Arrays.stream(request.getCookies()).
				filter(c -> c.getName().equals("myPreferredLocale")).findFirst().orElse(null);
				
            if(localeCookie != null){
                session.setLocale(new Locale(localeCookie.getValue()));
            }
        });
    }
}

Now with this code implemented, you will still need a way for the user to set this cookie. For this, I have made a [Language switcher component]
(https://stackoverflow.com/a/53763977/3441504). It currently only sets the locale of the current Session, but you can adapt the valueChangeListener to set a cookie that will from then on be used in the above session init listener.