I think there is a bit of confusion here about the role of the heartbeats.
The heartbeat goal is to keep the server-side UI alive while the browser page is still open on a Vaadin application page. If the browser gets close, the heartbeats are not sent anymore, and after 3 missing requests, the server-side UI is closed.
What I think you want is something different: if the user is idle and the session timeout is reached, you want the browser to be redirected to the login page.
So there is a distinction between UI expiration and User session expiration (and by User session here we mean the Vaadin session, not the HTTP session)
You can look at the linked documentation for a better explanation, but in short:
the heartbeats keep the UI active, but if there are only heartbeat requests for the amount of time defined as HTTP session timeout, the Vaadin session gets closed and a Session expired message is sent to the client, that reacts based on the SystemMessages settings (usually the client reloads the current page).
However, as pointed out in the docs, User session expiration does not mean HTTP session expiration
User session expiration does not imply the underlying HTTP session being invalidated. HTTP session invalidation can be performed by invoking invalidate on the WrappedSession accessible through VaadinSession.
This means that when page reload happens, the HTTP session is still valid, so the user is still authenticated.
To make sure the user is logged out, you need to invalidate the http session explicitly
You can handle user session expiration on the server side with a SessionDestroyListener , as described in User Session.
I hope this clarifies things for you