bigskysoftware / bigskysoftware/htmx

Links with hash don't apply `:target` properly when using hx-boost, `window.location.hash` should be manually reassigned

Open
#3,447 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
49.4k
Forks
1.7k
Avg merge
3d 22h
Merged PRs (30d)
30

Description

I have some headers on my site that have styles on `:target`. However, if I have hx-boost on some link to `/some-page#foo` and that page has an element with `id="foo"`, the `:target` style doesn't get triggered. I investigated and [according to the MDN documentation for `:target`](https://developer.mozilla.org/en-US/docs/Web/CSS/:target#description),

> The target element is set at document load and [`history.back()`](https://developer.mozilla.org/en-US/docs/Web/API/History/back), [`history.forward()`](https://developer.mozilla.org/en-US/docs/Web/API/History/forward), and [`history.go()`](https://developer.mozilla.org/en-US/docs/Web/API/History/forward) method calls. But it is *not* changed when [`history.pushState()`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) and [`history.replaceState()`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState) methods are called.

I presume that hx-boost uses `history.pushState()`, so that would explain why this is happening. The way to get around this is manually reassigning `window.location.hash` after each navigation event. (What I find a bit weird is that on navigation it does actually scroll down to the target element, so obviously the browser (or maybe htmx?) isn't completely oblivious to the change, but it still doesn't apply the style.)

Also, I'd like to add that this particularly causes issues when using htmx + missing.css, since missing.css has nice heading, etc. styles for `:target` and this will cause them to not appear.

I'm open to making a PR for this but I'm not familiar with htmx's source.

Thanks!


**Edit:** The workaround I'm using for my current project is as follows. I'm assuming that this event body verbatim could be put into htmx's handler for `htmx:afterSwap` and fix the issue, but maybe I'm missing something.

```JS
document.body.addEventListener("htmx:afterSwap", event => {
if (event.detail.boosted) {
window.location.hash = event.detail.pathInfo.requestPath.split("#")[1] || "";
}
});
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.