How to force browser to reload the whole page?

Hi!
I discover Turbo because of symfony/ux project. Awesome!
I use it with a complex sidebar that need a lot of CPU to be build. Next to the sidebar, I have a turbo-frame to load content.

<wrapper>
   <sidebar>
      <a href="foo" data-turbo-frame="content">foo</a>
   </sidebar>
   <turbo-frame id="content">
      ...
   </turbo-frame>
</wrapper>

It works very well, my application was faster! Awesome!
I discover that server can handle a header and it knows that I don’t need to build all the page, but only the core of the content! My application is now more faster! Awesoooome! :smile:

I only have a question. Sometime, user is disconnected, because of an expired session as example.

If he clicks on a link, the content is still updated, and user can see the login form in content. It’s exactly what I want to do. BUT, the sidebar is still displaying his avatar, the connected status, the logout button, etc.

With Twig and Symfony, I can remove all the turbo-frame from the answer. I’m sure it will force the browser to refresh the whole page. But is there a better solution? I mean, as the brower can send meta information, can server do it too ? Can the server send an HTTP header or something else to tell to the browser to refresh the whole page?

I’m not sure if I understood what you’re trying to achieve, but turbo_frames have the target="_top" attribute that replaces the whole page. Is that what you’re looking for?

You can check it here.

1 Like

Thanks for your answer @edcolen but I guess my problem wasn’t well explain. I try again.

My sidebar have to template. A non-logged template and a logged template.
User come on my website. Sidebar display a non-logged template. He logins. Because of target="_top" in login form. Sidebar is refreshed.
Logged user now see sidebar with the logged template (username, user role, avatar, and some links targeting the content turbo-frame)
User doesn’t use his browser during a long time.
Server side, the session expired.
User come back after a long break and click on the foo link in the sidebar.
As the session is expired, server send a 302 status to redirect him to login page, which display the login form.
Because of turbo, only the “content” turbo-frame is updated. The sidebar isn’t updated. Sidebar is displaying logged information, content is displaying the login form. I don’t this “weird” page.

I tried to remove turbo-frame in login response, but I only catch an empty page.

Yesterday, I update my application. Now when session reach timeout content display a message : You are disconnected. Please login. And I added a link with target="_top". It works, but I mean it’s an unnecessary step.

I want to find a solution, so server can tell to the client to refresh the whole page.

If you want to reload the page after the session is expired, you could use meta refresh and set the time to the session expiry duration.

There’s also this gem that you can use to have more control over the timeout behavior.

An alternative would be to implement the timeout actions you need on client side, using vanilla js or stimulus.

I would prefer following this client path than using server side logic, but it’s just my opinion.

1 Like

Thank you for your answer!

I will follow your advise and use stimulus to implement the timeout action.

I’m not aware of a strait forward way to do this, but you could listen to events from turbo:before-fetch-response and do a reload based on rules. Here’s an example of when a page is both redirected and the response url ends in “/login”, then it will reload the page.

The reason it reloads the page (instead of window.location.href=response.url is because in my rails app, a page reload will add the “flash” message when reloading and redirecting the page. Then the login page will display the flash message.

For me, the downside to this approach is I’m hitting the server twice (initial failed request from frame, and then hard reload). And this occurs with a frame load or a standard Turbo visit. So, in essence every time a user session times out it will his the server login page at least twice.

Note: this is untested, just a concept

document.addEventListener('turbo:before-fetch-response', function (event) {
  const response = event.detail.fetchResponse.response;
  if( response.redirected && response.url.match(/\/login$/) ) {
    window.location.reload()
  }
});
1 Like

turbo beta 5 (just release) now updates the src= to the frame request is redirected.

With this, you could add a stimulus controller to observe the src change.

import ApplicationController from './application_controller';

export default class extends ApplicationController {
  initialize() {
    this.observeMutations(this.srcListener, this.element, { attributes: true })
  }

  srcListener(events){
    if( this.element.src.match(/\/login$/) ){
      window.location.reload()
    }
  }
}
2 Likes

Thx for the response. While scrolling again through the docs. I found https://turbo.hotwired.dev/handbook/drive#setting-a-root-location which seems what I missed. Think like I should have search for root instead of base :see_no_evil: