router: router push gives DOMException: Failed to execute 'replace' on 'Location': 'http://localhost:8080undefined' is not a valid URL

Using router.push(path) but get an error as in the title. When looking at the debugger, it fails at the changeLocation line:

    function push(to, data) {
        const currentState = assign({}, history.state, {
            forward: to,
            scroll: computeScrollPosition(),
        });
        changeLocation(currentState.current, currentState, true);    // this is the line that fails

I can see in the debugger that to has the correct value but currentState.current is undefined. What could be the issue?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Workaround:

if you use history.pushState(...) directly alone with Vue router navigation you can avoid this problem by adding the current property yourself like this:

const new_state = {
   whatever: 'this is your data',
   current: '/'   // this is the workaround
}

window.history.pushState(new_state, '', '/next/path');

What was the problems? I used history.pushState(...) to keep the navigation state on the URL but this way of changing URL does not use the Vue router which sets for itself the current property every time. If you use history.pushState(...) directly it does not fail immediately but it does not set the current property. So it fails the next time you try to use the normal Vue router.

If you manage to reproduce, please open a new issue! Calling replaceState (or push) without passing the current state will fail. Do this:

history.replaceState(history.state, '', ...)

Even though it’s not documented, you can now pass a state property when pushing or replacing that will be passed to history.pushState. It’s likely to change though, it could become a different function since sometimes you just want to modify the current history entry’s state.

You can natively save state with history.replaceState({ ...history.state, ...myOwnState }, '') and it should not break the router.

I thought the form state was automatically saved by browsers 😄

I think, being able to pass state to history.state will go through an RFC at some point to make this behavior more explicit

@posva Thanks a lot, that did the trick. I was doing replaceState({}, '', ...) before since it was working in the previous router version. ありがとう!