solidjs / solid-router

A universal router for Solid inspired by Ember and React Router
MIT License
1.13k stars 143 forks source link

Setting `target="_self"` reloads the entire app when navigating #304

Closed aryzing closed 10 months ago

aryzing commented 10 months ago

Describe the bug

target="_self" is the default vale for links, so it should not be necessary to specify it. However, when specified, entire page is reloaded when clicking on an A link.

This behavior is problematic, for example, when A is passed to a third party library to render links, as is the case with solid-markdown.

Your Example Website or App

https://stackblitz.com/edit/solidjs-templates-ynwjsd?file=src%2FApp.tsx

Steps to Reproduce the Bug or Issue

Take a look at the reproduction above. Any clicking on any link with target="_self" will trigger a full page reload

Expected behavior

Given target="_self" is the default, the behavior with or without this attribute should be the same.

Screenshots or Videos

No response

Platform

All

Additional context

No response

Brendan-csel commented 10 months ago

There is some history here I think.

Ultimately users need a way to identify anchors that should be handled by the router (without a page refresh) from those that don't - ie because they're handled by some other back-end service outside the App.

The router currently has 3 ways (I think) to determine if it should ignore an anchor...

  1. if the <a> does not have a link attribute then the router ignores it. <A> does that for you by returning <a link .../>.
  2. if the <a> has a target then the router ignores it.
  3. if the <a> has particular rel attributes (download or external) then the router ignores it.

It seems like you are running into 2. There will be apps out there that use that method to get the router to ignore some anchors though - so not sure what the impact would be to change it now.

aryzing commented 10 months ago

Do you mean <a> or <A>? Seems that <a> is by default outside the router's control no? Isn't that the goal of having a router-aware <A>?

Brendan-csel commented 10 months ago

<A> just renders an <a link> in the DOM. The router listens for clicks on all <a>s and figures out if it should handle them (or not).

Relevant code in routing.ts

Brendan-csel commented 10 months ago

Isn't that the goal of having a router-aware <A>?

Even the new approach (since Oct 2022) of <A> automatically adding the link attribute has limitations.

For example you might create your own <FancyA> component (perhaps in a library) that internally renders an <A>. That is all great ...until you want <FancyA> to not be handled by the router. You then need to fallback to options 2 or 3 above with <FancyA target="_self"> having the least impact.

aryzing commented 10 months ago

Understood, seems it's working as intended, will close then. Thanks for clarifying @Brendan-csel