Inertia: Preserve #id_of_element in route after redirection

Created on 9 Oct 2019  路  7Comments  路  Source: inertiajs/inertia

Problem:
When inertia-link href attribute contains #some_id it is not preserved.

Example:
After click inertia-link with href="homepage#contact" it send us to //example.com/homepage, dropping "#contact" from url.

Expected behavior:
To keep #id in url and scroll to it's position after redirect

All 7 comments

For now I am marking proper behavior by getting hash before redirection, transform it to standard GET parameter, send a request with it and attach it to $page object with response, so I can scroll to desired location then. But I think that it should be somehow handled by Inertia itself.

Yeah, totally, this is something I need to figure out still. 馃憤

My proposal is to send X-Inertia-Hash header alongside with other headers.
And append the value of this header at the end of url which is sent to the front end on each Inertia response.

My another proposal would be to get the hash of the target URL before visiting it.
And execute location.href = hash after the axios request.

@reinink your thoughts?

@hivokas

My another proposal would be to get the hash of the target URL before visiting it.
And execute location.href = hash after the axios request.

It's not so simple: if you manipulate the hash bypassing Inertia (i.e. through location.href = "#hash" like in your proposal, or by click on a <a href="#hash" />), and then navigate somewhere through Inertia.visit (or InertiaLink, which uses Inertia.visit under the hood), the Back button will not work properly - it will change URL in the address bar back to #hash, but will not get you back to the page from which you visited the current one.

I tried to push history state instead, like in the example below, and it kinda worked: you can click on the link, then visit something else, and the Back button will properly get you back. But then if you try to Back one more time (which in normal circumstances must take you to the place where you clicked the link originally), you get stuck.

<a 
  href="#hash"
  onClick=(e => {
    e.preventDefault()
    document.getElementById("hash").scrollIntoView()
    history.pushState({...history.state, url: "/#hash"}, null, "/#hash")
  })
/>

The same happens in the opposite direction: if to modify your proposal to use replaceState instead of direct assignment to location.href, the Back button will work, but Forward will not - it will change address to #hash, but will not take to the page where you Back'ed from.

lastState = history.state
Inertia.visit("/").then(() => {
  history.replaceState({...lastState, url: "/#hash"}, null, "/#hash")
  document.querySelector('#hash').scrollIntoView()
})

// After running that code, click on Back will get you to the page on which 
// you run the code, but Forward will not take you to "/".

Browser: Chrome 80.0.3987.149

This has been fixed in #257, which just got merged in, and will be released soon. 馃檶

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ninjaparade picture ninjaparade  路  4Comments

ambethia picture ambethia  路  5Comments

philippkuehn picture philippkuehn  路  3Comments

piercemcgeough picture piercemcgeough  路  4Comments

sammagee picture sammagee  路  3Comments