#1104·go-app

Base Component Don't seem to work with Navigation

Author: GnyblastCreated Dec 23, 2025Updated Dec 23, 2025

I tried to create a base component that will be trying to hold app-wide boiler-plate components so that, I don't have to include these components everytime I create a new page, but instead I inherit the base component into my struct and they would just get picked up, also I was going to implement guards logic here:

base_view.go

go
package view

import (
	"example.com/app/components"
	"github.com/maxence-charriere/go-app/v10/pkg/app"
)

type Guard interface {
	CanActivate(ctx app.Context)
}

type BaseView struct {
	app.Compo
	view   app.Composer
	guards []Guard
	cloak  string
}

func NewBaseView(view app.Composer, guards []Guard) *BaseView {
	return &BaseView{
		view:   view,
		guards: guards,
		cloak:  "cloak",
	}
}

func (b *BaseView) Render() app.UI {
	return app.Div().Class(b.cloak).Style("width", "100%").Style("height", "100%").Body(
		b.view,
		components.NewPopUpDialog(),
		components.NewConfirmationDialog(),
		components.NewSnackBar(),
		components.NewLoader(),
		app.Script().Src("/web/scripts.js"),
	)
}

func (b *BaseView) OnMount(ctx app.Context) {
	for _, g := range b.guards {
		g.CanActivate(ctx)
	}

	b.cloak = ""
}

But the problem is when I use it as follows in app route:

main.go

go
	var authGuard = guard.AuthGuard{}
	var unAuthGuard = guard.UnauthGuard{}

	app.Route("/", func() app.Composer {
		return view.NewBaseView(&view.Login{}, []view.Guard{unAuthGuard})
	})
	app.Route("/login", func() app.Composer {
		return view.NewBaseView(&view.Login{}, []view.Guard{unAuthGuard})
	})
	app.Route("/home", func() app.Composer {
		return view.NewBaseView(&view.Home{}, []view.Guard{authGuard})
	})

The navigation starts to fail because it thinks that every one of these components are same thing because they are obviously same Type. I tried putting some string variables and a method that returns this variable like: key string and Key() string, so that each component looks not identical but that didn't help.

I got a workaround to make it work but that is also another level of boiler plate code for each page component. So I basically have Home as a page I created another HomeView:

home.go

go
type Home struct {
	app.Compo
}

type HomeView struct {
	BaseView
}

func NewHomeView(guards []Guard) *HomeView {
	return &HomeView{
		BaseView: *NewBaseView(&Home{}, guards),
	}
}

And when I use it this way in route with NewHomeView it works. But as I said this is more boiler-plate code introduced. Any proper way to achive this?

Source: maxence-charriere/go-app