#1119·go-app

Is it possible to have non-data state be loaded before first render in an SPA?

Author: Toms223Created Jun 8, 2026Updated Jun 8, 2026

Hi! My name is Tomás Martinho. I’m a Portuguese developer and was recently looking over at your project and started to implement a simple website with it.

So far I love it, I think you did a great job having a fully functional web-framework made in Golang while making it simple and intuitive to use. I had some trouble adapting to how things are handled, but after breaking a few of my bad habits coming from JS front-end it did smooth out.

I only have a question to you, regarding the specific use case of using Go-App as an SPA that I haven’t quite understood, and that I think you are more than the right person to answer.

When using tools like react, vue or anything of the sort is customary to have some kind of mechanism to handle the loading of non-data state. For example, a simple sidebar, it can be opened or closed, a simple boolean, and it is shared across all pages. In server-side mode I can handle which state the sidebar is in using a combination of OnPreRender and getting the state using app.Context. Now when using SPA I only have access to OnMount, which means I need a default value for the sidebar on first render, which might not be the same as the one stored in app.Context.

My workaround for this is using a simple isMounted variable set to false on first render and then set to true when all state is loaded in “OnMounted" which makes the first render only have a blank div or a simple loading screen. However this leads to some “ugliness” as the page flickers or shows a loading screen when one is not needed.

My question is the following, am I doing something wrong? Is there a mechanism I missed that allows me to have the state of the sidebar loaded without having to do the “isMounted” trick?

In JS frameworks this behaviour does not seem to exist, leading me to believe that there is some sort of logic on their side to load non-data state during or before the render. And this is the behavior I’d like to have, if at all possible.

Please take your time to respond to this, and a simple “Use x, y and z” would suffice.

Examples:

go
//Server Side example

const isOpenState = "sidebar/open"

type Sidebar struct{
     app.Compo
     isOpen bool
}

func (s *Sidebar) OnPreRender(ctx app.Context) {
    var isOpen bool
    ctx.GetState(isOpenState, &isOpen)
    s.isOpen = isOpen
}
//Render Logic
go
//Spa example
type Sidebar struct{
     app.Compo
     isOpen bool
     isMounted bool
}

func (s *Sidebar) OnInit(){
    s.isMounted = false //bool default value is already false, just added this to emphasize
}

func (s *Sidebar) OnMount(ctx app.Context) {
    var isOpen bool
    ctx.GetState(isOpenState, &isOpen)
    s.isOpen = isOpen
    s.isMounted = true
}

func (s *Sidebar) Render() app.UI {
    if !s.isMounted {
        return App.Div()
    }
    //Render Logic
}

Source: maxence-charriere/go-app