hilla icon indicating copy to clipboard operation
hilla copied to clipboard

Application should not be shown for a moment for non-handled routes

Open abdullahtellioglu opened this issue 6 months ago • 8 comments

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

abdullahtellioglu avatar Jun 05 '25 10:06 abdullahtellioglu

How is the login page built? It should perhaps prevent layout from being used to avoid the described effect.

mcollovati avatar Jun 05 '25 11:06 mcollovati

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"));
    }
}

abdullahtellioglu avatar Jun 05 '25 11:06 abdullahtellioglu

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.

Image

mcollovati avatar Jun 06 '25 08:06 mcollovati

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.

mshabarov avatar Jun 06 '25 09:06 mshabarov

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,

mcollovati avatar Jun 06 '25 09:06 mcollovati

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/>
    );
}

mcollovati avatar Jun 06 '25 10:06 mcollovati

Let us investigate in Hilla to find if there is a way to implement this use case without flashing the Hilla layout.

platosha avatar Jun 17 '25 11:06 platosha

Seems to be a missing feature rather than a bug so far.

platosha avatar Jun 17 '25 11:06 platosha

One idea to prototype here: define or move the suspense boundary to be around the main layout and make Flow a lazy route.

platosha avatar Aug 19 '25 11:08 platosha