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

Link to external resource under the same domain

thejezzi opened this issue · comments

commented

Hi there,

I was wondering, is there a way to forcefully redirect to an external resource under the same domain?
I have two apps hosted under the same domain name and whenever I try to link to a different page the client side router tries to take over. Am I missing something or is this supposed to happen?
I don't have a wildcard route or something that matches the URI that I'm calling or is the router trying to match everything?

    a.A().
    Target("_blank").
    Href(a.Window().URL().Scheme+"://"+a.Window().URL().Host + External(id)).
    Body(
        a.Raw(R2QueryIcon),
    ).
    Title("External Resource")

See this code for anchor click handling:

func onAchorClick(d Dispatcher) func(Value, []Value) any {

It is setup during go-app startup:

onAchorClick := FuncOf(onAchorClick(&disp))

Without changing go-app code, the onClick events are going to be captured on anchor tags and treated as internal navigation if the host matches.

You can get around this by setting window.location.href in an on click event:

	app.A().Style("cursor", "pointer").OnClick(func(ctx app.Context, e app.Event) {
		u, _ := url.Parse(app.Window().URL().String())
		u.Path = "/other"
		app.Window().Get("location").Set("href", u.String())
	}).Text("/other path on same host"),

This is exactly what go-app does when navigating to urls that it thinks are external:

if isExternalNavigation(u) {

commented

Thank you!

My only problem with this is that the user is no longer able to right click and open the link in a new tab for example or copy the link to e.g. share etc. because of the missing href on the anchor itself. I know that I could tweak the onclick event to open the link in a new tab everytime but for anything else I dont think this is real solution.

I saw that the navigate function gets avoided when either two events are set or the download attribute has some content and I build a "External" component to get my desired behaviour:

// IExternal is the interface for the external link component
type IExternal interface {
	a.UI

	Class(string) IExternal
	ID(string) IExternal
	Style(key, value string) IExternal
	Href(string) IExternal
	Label(string) IExternal
	As(a.UI) IExternal
}

type UiExternal struct {
	a.Compo

	HrefVal     string
	LabelVal    string
	ClassVal    []string
	IDVal       string
	StyleVal    [][2]string
	ChildrenVal a.UI
}

func External() IExternal {
	return &UiExternal{}
}

func (ex *UiExternal) Href(href string) IExternal {
	ex.HrefVal = href
	return ex
}

func (ex *UiExternal) Label(label string) IExternal {
	ex.LabelVal = label
	return ex
}

func (ex *UiExternal) As(children a.UI) IExternal {
	ex.ChildrenVal = children
	return ex
}

func (ex *UiExternal) Class(class string) IExternal {
	ex.ClassVal = append(ex.ClassVal, class)
	return ex
}

func (ex *UiExternal) ID(id string) IExternal {
	ex.IDVal = id
	return ex
}

func (ex *UiExternal) Style(key, value string) IExternal {
	ex.StyleVal = append(ex.StyleVal, [2]string{key, value})
	return ex
}

func (ex *UiExternal) Render() a.UI {
	anchor := a.A()

	for _, style := range ex.StyleVal {
		anchor.Style(style[0], style[1])
	}

	return anchor.
		Class(ex.ClassVal...).
		ID(ex.IDVal).
		Href(ex.HrefVal).
		OnClick(func(ctx a.Context, e a.Event) {
			e.PreventDefault()
			a.Window().Get("open").Invoke(ex.HrefVal)
		}).
		Attr("download", "external").
		Text(ex.LabelVal).
		Body(
			ex.ChildrenVal,
		)
}

@maxence-charriere I think that there should be a way to do that by adding something to the HTML element, that tells go-app to not handle this A tag. Having to work around this limitation looks odd.