Navigating to local URL fragment doesn't modify browser history

When I include a link to a section in a page - that link, when clicked, does not modify the browser history. Navigating back proceeds to navigate away from the pager, rather than return to page position where the link is defined.

Edit: Well on this Discourse I’m unable to create an element with an ID, so I can’t demo this here. The source here is what I’d like to be doing - but this is just to illustrate and doesn’t impact the gist of my issue:

<div id="link-target"></div>

*This section is linked to from above. Nothing to see here.*
1 Like

This is kinda of expected. If you click a link to another post in the same topic it is also not pushed into the history stack, and it is a full link without fragments, so we never push in-topic into the history.

1 Like

I find this behavior extremely unexpected :slight_smile:

Here’s a sample page with no JavaScript. On Chromium, clicking that link takes you to the bottom of the page. Clicking back takes you back to where you clicked from. That’s expected behavior that you’ll see on every other website that doesn’t eat this history.

<a href="#target">link</a>

<div style="height:2000px"></div>

<div id="target">Hello</div>

I assume Discourse is handling URL fragments in JavaScript by scrolling to the location and therefore the history would have to be explicitly pushed.

@codinghorror expresses a strong and final opinion about this here. It’s surprising to see such a strong opinion about a change to standard web browser behavior. In fairness I haven’t yet used Discourse for heavy duty topic navigation and therefore can’t appreciate the obviousness of his argument.

I’m using Discourse in part for documentation and this behavior is extremely disruptive to the point that I’m afraid to click a link and lose my place on a page.

1 Like

Here’s an example of where this behavior is problematic:

https://meta.discourse.org/tos

If you’re tempted to click any of the TOC links and then return to your starting point via browser history, you can’t.

Why provide a TOC in the first place?

For those sites that would like to support the standard browser navigation, any suggestions?

I’m looking into monkeypatching the scroll-to-element behavior that I suspect is behind this but I’m starting with literally no knowledge of the codebase :slight_smile: I’ll get there eventually but if someone has some pointers, I appreciate the help!

1 Like

Depending on the context which you’ll use your anchors in, maybe this table of content plugin could be useful (and in my opinion that would fit well on the TOS and FAQ page)?
Example here.

1 Like

I never realized this was bothering me until you pointed it out. I’ve often tried to go back to where I clicked a link in Discourse and instead ended up on a previous page. Very irritating. I always chalked it up to a combination of the iOS app, since I use it for almost all Discourse stuff, and user error.

1 Like

This TOC component is really well done and we’re using it in every docs page - very grateful for the work put into it!

The issue of navigation remains however. Clicking a link in the TOC does not modify the browser history and therefore navigating back navigates off the page.

1 Like

This is certainly the case, It would be nice to fix this @Johani but I have a feeling it is very complicated. Maybe we just pushstate when you click on a TOC link

5 Likes

I implemented a work-around (arguably a proper approach to customize a site given Discourse’s point-of-view on link navigation) via a theme component. This follows the pattern used by DiscoTOC where a marker is added to a post to trigger the behavior. The applicable code is here.

I think modifying DiscoTOC to use URL fragments and browser history is a good idea. This requires changing the component’s approach to navigation, which is not a minor change. DiscoTOC uses data attributes to pass along targets rather than link href’s. There’s no attempt to reflect the new page location in the browser URL (window.location).

I think the pattern I’m using above could work for DiscoTOC but that has broader implications for that component given its current approach.

2 Likes

careful with pushstate there… what you probably want is replacestate.

I think pushState in this case. The goal is to enable back-to-previous-position, which requires a push to history because the event is prevented.

This is why there used to be little “return to top” links at the bottom of each (adapting for this example) TOS entry… :thinking: