How to keep persistent socket assigns between different LiveViews

Hello everybody;
I am working on some web application and I have issue that I couldn’t solve, this is the first time I post question here, so I would really appreciate any help or guide.

Have 3 languages (Locales)

My application has 3 languages, the problem is when I navigate from one live view to the other, I lose the assigned locale. Say I am on the about_live and I selected from drop menu the German language, when I navigate away from that LiveView to another one say admission_live I find the default locale was selected and I can’t keep persistent assigns. I tried to set it in session but again it is not persistent between LiveViews. I even made that drop languages component as standalone liveview so it will be common between all other views, but because all of them use the same Layout it lose any state.

Thanks a lot.

You have several questions and some of them are unrelated to the title. I suggest you to break them out to a separate posting.

You can’t persist socket assigned across different LiveViews such as the transition resulting from push_redirect. The reason is the old view process dies before the new process comes alive, so there is no chance to hand off the data.

However, it is possible to keep some vital state (Locale, for example) in the client side in localStorage then re-submit them to the new LiveView through pushEvent using a mounted hook.

1 Like

Yes I understand about old process die before new one spawn. That’s why I asked if there is some way to handle such problem, I will try your solution, and what I understood from it is to keep the locale value in the localeStorage so if user changed locale, event will be pushed to his localeStorage with the selected locale and when he navigate away to another live view his browser send event with the value of that locale and I should handle that in each live view I have? Did I understand you right?!

localStorage is a simple K/V store provided by the browser’s JS api and also silo’ed by origin. Two different kinds of infos can be submitted to the liveView upon mount:

  • fundamental info from the browser, such as language or timezone. they do not need to be stored, but merely regathered. eg: navigator.language and new Date().getTimezoneOffset()
  • Something you put in the localStorage. They are kind of like cookies, but fully under your control. For example security tokens.

Otherwise, your understanding is correct. I think this is better than trying to persist them in the server side with ETS or something because those things are client specific, not user specific:

  • per client info shall persist on the client side: A user may have several clients: computers, phones etc.
  • per user info shall persist on the server side, such as a shopping cart. The user can hop between different clients and have a unified experience

I REALLY appreciate your reply and your time spent in it. Thanks a lot for your clear explanation.

Another option is to just append a query string parameter to the route when anything other than the default locale is selected. This way even the first render (disconnected state) would be in the correct locale if the link was shared.

I would imagine, using the local storage method, that you would have to render once in the default locale and have the JS pull the value from local storage, then fire a LiveView event to force the change to the new locale, which might be visually jarring as it would rerender (likely most of your static markup would change too, not just the assigns). Having it in the params means it would be correct right away.

Downside is that you have to ferry the locale param across the redirects, but a lot of dead view sites do something similar. If your users share links, they may appreciate being able to have the correct language set for whomever they share it with via that link.

Alternatively, if your users are authenticated, you could also store the preference on the user record, setting it upon auth so when they return/navigate you already have it.

If not authenticating, then you could have the LV do post to a dead view that sets the desired locale (thereby getting it on the session and then socket) which redirects to the desired page which you’d pass as a param, since you likely will be re-rendering it anyway to get the static markup into the new language.

All depends upon the user experience you desire.

True. However I gave up on the static rendering already, so it is just a loading... string. It is still some visual glitch but it kind of match with the initial behavior of many javascript SPA out there.

Query string is ugly. If it is just language it is probably ok but I have many other things to pass. I don’t want to look like a advertiser that try to track my visitors :slight_smile: