Hello,
I’m using Jmix (v2.7) with a custom login view and a custom LoginViewSupport extension. I’m trying to keep the user’s locale when they log in with Remember me and then completely close and reopen the browser.
Currently, the behavior is:
- Within the same browser session (e.g. close tab and open new tab) – the locale works as expected.
- If I close the whole browser and reopen it – the user is automatically logged in via remember-me, but the UI appears in the default English locale, even though the user’s preferred locale is stored in the database (e.g.
uz).
Below are the relevant pieces of code.
1. Custom LoginViewSupport
I have a custom bean extending LoginViewSupport, mainly to support Telegram login by username only:
@SpringComponent("my_LoginViewSupport")
@Primary
public class MyLoginViewSupport extends LoginViewSupport {
@Autowired
private SystemAuthenticator systemAuthenticator;
public void authenticate(String username, Locale locale) {
Authentication authenticationToken = createAuthenticationToken(
username,
null,
locale,
null
);
AbstractAuthenticationToken systemToken =
(AbstractAuthenticationToken) systemAuthenticator.begin(username);
systemToken.setDetails(authenticationToken.getDetails());
Authentication authentication = authenticationManager.authenticate(systemToken);
preventSessionFixation(authentication);
onSuccessfulAuthentication(
authentication,
AuthDetails.of(username, null)
.withLocale(locale)
);
}
}
For the regular login with username/password I use the inherited authenticate(AuthDetails) method.
2. Custom LoginView
My login view does the usual checks and then calls authenticate(AuthDetails) with both locale and remember-me flag:
@Route("login")
@ViewController("My_LoginView")
@ViewDescriptor("login-view.xml")
public class LoginView extends StandardView {
@Autowired
private MyLoginViewSupport myLoginViewSupport;
@ViewComponent
private Input username;
@ViewComponent
private JmixPasswordField password;
private ToggleButton rememberMeToggle;
private LoginLocaleComponent localeComponent;
@Subscribe
public void onInit(InitEvent event) {
// custom remember-me toggle (Vaadin component)
inputs.addComponentAtIndex(2, addRememberMeButton());
// custom locale component (combobox with locales)
localeComponent = uiComponents.create(LoginLocaleComponent.class);
loginMain.add(localeComponent);
}
@Subscribe("loginBtn")
public void onLoginClick(ClickEvent<VerticalLayout> event) {
String usernameValue = String.valueOf(username.getValue()).trim();
String passwordValue = String.valueOf(password.getValue()).trim();
try {
Locale selectedLocale = localeComponent.locale();
jbLoginViewSupport.authenticate(
AuthDetails.of(usernameValue, passwordValue)
.withLocale(selectedLocale)
.withRememberMe(rememberMeToggle.getValue())
);
// Optionally store the locale in DB:
userService.saveUserLocale(usernameValue, selectedLocale.getLanguage());
errorsContainer.removeAll();
} catch (LockedException ex) {
// ...
} catch (BadCredentialsException ex) {
// ...
} catch (AuthenticationException ex) {
// ...
}
}
}
So, on first login:
- the locale is taken from the user’s selection in
LoginLocaleComponent, - and passed to
AuthDetails.withLocale(...)together withwithRememberMe(...).
3. Applying user locale in MainView (for remember-me sessions)
On application main view I also try to enforce the user’s preferred locale from DB, so that it works even for remember-me auto-login:
@Route("")
@ViewController("my_MainView")
@ViewDescriptor("main-view.xml")
public class MainView extends StandardMainView {
@Autowired
private UserService userService;
@Autowired
private CurrentAuthentication currentAuthentication;
@Subscribe
public void onInit(InitEvent event) {
User user = userService.currentUser();
if (user != null) {
try {
String lang = userService.getUserLocale(user.getUsername());
if (lang != null) {
Locale locale = Locale.forLanguageTag(lang);
UI.getCurrent().setLocale(locale);
}
} catch (Exception ignored) {
}
}
// ... rest of init logic (theme, user profile, navigation, etc.)
}
}
This means:
- For normal login – locale is set via
AuthDetails.withLocale(selectedLocale)and also applied inMainViewfrom DB. - For remember-me auto-login –
LoginViewis not opened, butMainView.onInit()still runs, andUI.getCurrent().setLocale(locale)is called with the DB value.
Despite this, when I:
- Log in with a non-default locale, e.g.
uz; - Check Remember me;
- Close the whole browser;
- Reopen it and go to the app URL;
the user is automatically authenticated (as expected) but the UI appears in English. If I simply close the tab and open a new tab (without closing the whole browser), the locale is correct.
4. Question
Is there a recommended way in Jmix 2.7 to:
- Keep the user’s locale across sessions when using remember-me (including when the whole browser is closed and reopened)?
- Or, more specifically, to ensure that after a remember-me auto-login, the UI locale is properly taken from the user’s DB setting instead of reverting to the default (English)?
If I’m missing some configuration or an appropriate place to apply the locale for remember-me sessions, I’d appreciate any guidance or best practices.
Thank you!