Coder Social home page Coder Social logo

Comments (11)

ldanielduarte avatar ldanielduarte commented on June 10, 2024 6

Hello guys,

I'm sorry to write this here because it is not an issue or a bug report, just some support request - but it seems that the topic fits very well in the difficulty that I am having and I am sure that @reinink will be able to help me 😄

When redirecting from the controller:

class EntityController extends Controller
{
    public function store(Request $request): RedirectResponse
    {
        ....
        return redirect()->route('entities.list')->withFragment('manage');
    }
}

How can I keep the hash in the URL?

For instance, in this case, return to the page https://domain.com/entities#manage

I am suspecting that Inertia is doing some magic behind in this case, because I am not being able to keep the hash in the URL and from what it is written in Laravel docs, it seems that it should be possible.

Here is the reference for what I am using:
Laravel @ GitHub - RedirectResponse class, withFragment method

Maybe Inertia does not handle this cases yet? Is this something already being considered in the road map?

I've also opened a discussion in stackoverflow to see if someone from the community there can give some feedback.

from inertia.

anatoliyarkhipov avatar anatoliyarkhipov commented on June 10, 2024 3

@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

from inertia.

reinink avatar reinink commented on June 10, 2024 1

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

from inertia.

hivokas avatar hivokas commented on June 10, 2024 1

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.

from inertia.

ldanielduarte avatar ldanielduarte commented on June 10, 2024 1

@ldanielduarte did you manage to get this working? I am currently facing the exact same problem and already tried the things you tried. Like using the withFragment().

Yes I've managed to get it working.

  • I've created a list of "NavItems" in the backend;
  • If it is a request from the Frontend with a fragment that it is necessary to keep, when the request arrives in the backend, the URL fragment is parsed and stored in memory;
  • The selected NavItem is returned in the body of the response.

It is not the most elegant solution, and the most negative point is having to manage the NavItem names (the names existing in the frontend must match the list in the backend). But it is safe, it practically does not impact the performance and it works very well.

Example:
image

from inertia.

smbdelse avatar smbdelse commented on June 10, 2024

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.

from inertia.

hivokas avatar hivokas commented on June 10, 2024

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.

from inertia.

hivokas avatar hivokas commented on June 10, 2024

@reinink your thoughts?

from inertia.

reinink avatar reinink commented on June 10, 2024

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

from inertia.

Baspa avatar Baspa commented on June 10, 2024

@ldanielduarte did you manage to get this working? I am currently facing the exact same problem and already tried the things you tried. Like using the withFragment().

from inertia.

Baspa avatar Baspa commented on June 10, 2024

@ldanielduarte I asked in the Inertia Discord channel about this and @RobertBoes gave me the following answer:

I don't think that'll ever work, because the request is made using XHR. So the browser will deal with the redirect.

Quickly tried it in PingCRM, the response is a 302 with the following header: Location: http://pingcrm.test/contacts#something so the correct redirect URL is set. However, the followup request is made by the browser which is just GET http://pingcrm.test/contacts. So the browser will discard the fragment, afaik this isn't something Inertia can do anything about. Even the underlying library has no impact (Axios), because the browser itself will do the redirect, not Axios.

XHR requests are always made without a fragment, as seen here: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseURL any URL fragment present in the URL will be stripped away.

Can't find the RFC that that has all this explained right now, but iirc it's just how these requests work. For example, if you do Inertia::get('/dashboard#something') then Inertia will strip the fragment from the URL, make the request and after the request is completed it will add the fragment back to the URL using the History API, because the fragment is not sent along with the XHR request.

from inertia.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.