maxence-charriere / go-app

A package to build progressive web apps with Go programming language and WebAssembly.

Home Page:https://go-app.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Some content double rendering in the browser

jsgoecke opened this issue · comments

I have everything working with the framework fine, except some of the content renders twice on the web page. I am not attempting to render twice, AFAIK, so thinking this could be related to something deeper in the framework and related libraries used. Has anyone seen this and/or have a recommendation?

What do you mean with "render twice"? Is "Render()" called twice or are you nodes in the DOM rendered "twice" and how do you know that?

Edit: Actually I wonder if you mean that the delievered page gets updated in the frontend, which what Go-App is for. You don't use it for rendering stuff "server side" for being shown in the frontend. This is merely for visitors that do now start the go-app framework (like webscrapers).

These are duplicates in the same render on the indexPage:

Screenshot 2023-12-11 at 3 39 04 PM

Here is my main.go:

package main

import (
	"log"
	"net/http"

	"github.com/maxence-charriere/go-app/v9/pkg/app"
)

// Log HTTP requests
func logRequest(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("Received request: %s %s", r.Method, r.URL)
		next.ServeHTTP(w, r)
	})
}

// The main function is the entry point where the app is configured and started.
// It is executed in 2 different environments: A client (the web browser) and a
// server.
func main() {
	// The first thing to do is to associate the hello component with a path.
	//
	// This is done by calling the Route() function,  which tells go-app what
	// component to display for a given path, on both client and server-side.
	app.Route("/", &indexPage{})
	app.Route("/about", &aboutPage{})
	app.Route("/contact", &contactPage{})

	// Once the routes set up, the next thing to do is to either launch the app
	// or the server that serves the app.
	//
	// When executed on the client-side, the RunWhenOnBrowser() function
	// launches the app,  starting a loop that listens for app events and
	// executes client instructions. Since it is a blocking call, the code below
	// it will never be executed.
	//
	// When executed on the server-side, RunWhenOnBrowser() does nothing, which
	// lets room for server implementation without the need for precompiling
	// instructions.
	app.RunWhenOnBrowser()

	// Finally, launching the server that serves the app is done by using the Go
	// standard HTTP package.
	//
	// The Handler is an HTTP handler that serves the client and all its
	// required resources to make it work into a web browser. Here it is
	// configured to handle requests with a path that starts with "/".
	http.Handle("/", &app.Handler{
		Name:        "Thive PE",
		Description: "Thrive PE Website",
	})

	if err := http.ListenAndServe(":8000", nil); err != nil {
		log.Fatal(err)
	}
}

It looks like you do something wrong in the component that is rendering this page. The main is okay as is.

I simply can't see it, here is the indexPage.go.

package main

import "github.com/maxence-charriere/go-app/v9/pkg/app"

// indexPage is a component that displays a the index page. A component is a
// customizable, independent, and reusable UI element. It is created by
// embedding app.Compo into a struct.
type indexPage struct {
	app.Compo
}

func renderMenu() app.UI {
	return app.Div().Class("menu").
		Body(
			app.A().
				Href("/").
				Text("Home"),
			app.A().
				Href("/about").
				Text("About"),
			app.A().Href("/contact").
				Text("Contact"),
		)
}

// The Render method is where the component appearance is defined.
func (h *indexPage) Render() app.UI {
	return app.P().Body(
		app.Link().
			Rel("stylesheet").
			Href("/web/thrive-pe.css"),
		app.Img().Src("web/images/thrive-pe-logo.png").
			Height(100).
			Alt("Thrive PE Logo"),
		renderMenu(),
		app.Div().Class("parent").
			Body(
				app.Div().Class("left-square").Body(
					app.Img().Src("web/images/spiral.png").
						Class("spiralImage").
						Alt("spiral"),
				),
				app.Div().Class("right-square").Body(
					app.H1().
						Text("Proactive Risk Management").
						Class("title"),
					app.P().
						Text("Thrive Private Equity fund is focused on the operational carveout of high-growth opportunities in healthcare, insurance, cyber, and other industries."),
				),
			),
	)
}

Well, I do not immediatly see a problem there. Did you check what elements are getting created in the browser?

P.S.: Placing the <link> tag inside of the body is maybe not the best thing. You can add that to the raw HTML of app.Handler and don't forget to add all your assets to the app.Handler() too.

Are you on a stable branch?, it look like something i got while working on v10.

I am on github.com/maxence-charriere/go-app/v9 v9.8.0 // indirect. So not on v10 or a non-stable branch AFAIK.

@oderwat That is the weird part that I forgot to call out. While it is rendered in the browser twice, the HTML in the dev console shows only once instance and what should be the valid HTML.

Did you try it without the css?

I did try without CSS. When I commented out this line in main.go: "app.RunWhenOnBrowser()" it stopped double rendering and works fine.

When I commented out this line in main.go: "app.RunWhenOnBrowser()" it stopped double rendering and works fine.

This can't be the solution. If that line is missing, there is no frontend, and it will only show the pre-render version of the page (AFAIK).

You do compile the executable and the WASM code separately, right?

Maybe you want to try out some other code to have some references:

https://github.com/metatexx/go-app-todo
https://github.com/oderwat/go-nats-app
https://github.com/oderwat/go-guess-the-number-app

P.S.: Have you tried to leave out the app.Link() part. This usually goes into HEAD of the page (using the RawHeaders of app.Handler)

Yes, I did move that to the proper place and out of the body. And yeah, the whole point is to have the frontend load. Thank you for the links.