hilla
hilla copied to clipboard
Application should not be shown for a moment for non-handled routes
Description of the bug
As you can see from the video, the application shows up for a half second, then the login page is shown. The "" route does not exist, so it has nothing to do with authentication. There is no 404 page registered either.
https://github.com/user-attachments/assets/3e7144a7-9e9f-4c39-827d-5209da65484e
Expected behavior
The application should not be seen.
Minimal reproducible example
- Create an application with more than one views.
- Open a route view in browser
- Delete the view from the code
- Restart the application.
- Reload the page.
Versions
Hilla: 24.8.0.beta2 Flow: 24.8.0.beta2 Vaadin: 24.8.0.beta2 Spring Boot: 3.5.0 Spring: 6.2.7 Spring Security: Spring Data JPA: Copilot: 24.8-SNAPSHOT Frontend Hotswap: Enabled ⋅ Vite OS: aarch64 Mac OS X 14.7.1 Java: JetBrains s.r.o. 21.0.6 Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36 Java Hotswap: Java Hotswap is enabled IDE Plugin: 1.0-SNAPSHOT IntelliJ
How is the login page built? It should perhaps prevent layout from being used to avoid the described effect.
I think it is a bug related to React router
Here is LoginView.java.
@AnonymousAllowed
@PageTitle("Login")
@Route(value = "login")
public class LoginView extends LoginOverlay implements BeforeEnterObserver {
private final AuthenticationContext authenticationContext;
public LoginView(AuthenticationContext authenticationContext) {
this.authenticationContext = authenticationContext;
setAction(RouteUtil.getRoutePath(VaadinService.getCurrent().getContext(), getClass()));
LoginI18n i18n = LoginI18n.createDefault();
i18n.setHeader(new LoginI18n.Header());
i18n.getHeader().setTitle("My App");
i18n.getHeader().setDescription("Login using user/user or admin/admin");
i18n.setAdditionalInformation(null);
setI18n(i18n);
setForgotPasswordButtonVisible(false);
setOpened(true);
}
@Override
public void beforeEnter(BeforeEnterEvent event) {
if (authenticationContext.isAuthenticated()) {
setOpened(false);
event.forwardTo("");
}
setError(event.getLocation().getQueryParameters().getParameters().containsKey("error"));
}
}
The issue is reproducible also in 24.7.
No need for Spring Security, just create a Flow + Hilla application (npm init vaadin) with a Hilla @layout.tsx and add a Flow view using login overlay, then directly open (http://localhost:8080/login) and verify that the layout is shown for a while until the Flow view is loaded.
Setting a custom layout on the Flow side seems to not fix the issue:
@Route(autoLayout = false)@Route(layout = LoginView.MyLayout.class))@Layout("/login")
@Route(value = "login")
public class LoginView extends LoginOverlay {
public LoginView() {
setAction("login");
setOpened(true);
}
}
In addition, the Flow layout seems to be rendered inside the Hilla layout, but I don't remember if this is the expected behavior or a bug.
In addition, the Flow layout seems to be rendered inside the Hilla layout, but I don't remember if this is the expected behavior or a bug.
This is expected. We don't yet support both Hilla and Flow layouts at the same time.
This is expected. We don't yet support both Hilla and Flow layouts at the same time.
Given that, this is probably not a bug, but the currently expected behaviour, even if the result is visually annoying,
Possible workaround: implement a login view in Hilla skipping layout, potentially importing the Flow component
public class LoginExporter extends WebComponentExporter<LoginView> {
public LoginExporter() {
super("app-login");
}
@Override
protected void configureInstance(WebComponent<LoginView> webComponent, LoginView component) {
}
}
public class LoginView extends LoginOverlay {
public LoginView() {
setAction("login");
setOpened(true);
}
}
import {reactElement} from 'Frontend/generated/flow/Flow';
import type {ViewConfig} from '@vaadin/hilla-file-router/types.js';
export const config: ViewConfig = {
title: "Login",
loginRequired: false,
skipLayouts: true,
menu: {
exclude: true,
},
};
function LoginComponent() {
return reactElement('app-login');
}
export default function LoginView() {
return (
<LoginComponent/>
);
}
Let us investigate in Hilla to find if there is a way to implement this use case without flashing the Hilla layout.
Seems to be a missing feature rather than a bug so far.
One idea to prototype here: define or move the suspense boundary to be around the main layout and make Flow a lazy route.