-
-
Save Intrepidd/ac68cb7dfd17d422374807efb6bf2f42 to your computer and use it in GitHub Desktop.
// DISCLAIMER : You can now probably use `data-turbo-action="advance"` on your frame to perform what this controller is aiming to do | |
// https://turbo.hotwired.dev/handbook/frames#promoting-a-frame-navigation-to-a-page-visit | |
// Note that you probably want to disable turbo cache as well for those page to make popstate work properly | |
import { navigator } from '@hotwired/turbo' | |
import { Controller } from '@hotwired/stimulus' | |
import { useMutation } from 'stimulus-use' | |
export default class extends Controller { | |
connect (): void { | |
useMutation(this, { attributes: true }) | |
} | |
mutate (entries: MutationRecord[]): void { | |
entries.forEach((mutation) => { | |
if (mutation.type === 'attributes' && mutation.attributeName === 'src') { | |
const src = this.element.getAttribute('src') | |
if (src != null) { | |
const url = new URL(src) | |
navigator.view.lastRenderedLocation = url | |
navigator.history.push(url) | |
} | |
} | |
}) | |
} | |
} |
@Intrepidd, sorry, I've double-checked this, and it is working as expected.
How does one use this stimulus controller? I added a data-controller attribute to frame, to div encompassing links that do not update the url, and still nothing. Cannot get history to change using this.
How does one use this stimulus controller? I added a data-controller attribute to frame, to div encompassing links that do not update the url, and still nothing. Cannot get history to change using this.
@cc-ray-boutotte the controller is to be attached to the frame like so :
<turbo-frame data-controller="turbo-frame-history" id="xxx">
Does anyone else have duplicate entries? for now I "fixed" it with an extra check
import { navigator } from '@hotwired/turbo';
import { Controller } from '@hotwired/stimulus';
import { useMutation } from 'stimulus-use';
export default class extends Controller {
connect() {
useMutation(this, { attributes: true });
}
source = null;
mutate(entries) {
entries.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
const src = this.element.getAttribute('src');
if (src != null) {
if (this.source !== src){
navigator.history.push(new URL(src));
this.source = src;
}
}
}
});
}
}
@Selion05 do you have the controller multiple times on the same page? Or nested in each other?
No I don't. Just double checked and created a random number which i log inside the controller... It is just one controller instance...
New iteration to prevent issues when fiddling with the history.
Issue was :
Frame visit A
Frame visit B
Frame visit C
Hit prev
Frame visit D
Hit prev
Nothing would happen
Hi @Intrepidd, is this solution still needed with the new additions to hotwire?
Thanks for the hard work!
Thanks for challenging the status quo, actually I just discovered data-turbo-action
introduce in v 7.2.0 appears to do the trick : https://turbo.hotwired.dev/handbook/frames#promoting-a-frame-navigation-to-a-page-visit
Hi @Intrepidd , It seems that the turbo-action advance updates the URL but it refreshes the whole page.
Also, have you seen issues on the history back button on your solution?
@michelson I don't experience the refreshing of the whole page with data-turbo-action="advance"
, maybe the refresh is caused by something specific to your app ?
And yes, I've seen issues with my solution when playing back and forth with the history, I'm glad I was able to drop it for a more native solution :)
Hi @Intrepidd, not sure why I get that behavior, what I have is a link outside the frame that is visiting the frame, like:
<a data-turbo-frame="conversation" href="...">link</a>
<turbo_frame_tag "conversation" data-turbo-action="advance" src="...">...</>
Could happen that the browser refresh is due because the link is outside the frame?
@michelson I am not sure to follow, if you have a form with target _top and use my controller the URL won't change after the redirect ?