Next.js: Router.beforePopState not firing

Created on 20 Jul 2018  路  26Comments  路  Source: vercel/next.js

Bug report

I'm unable to get beforePopState trigger.

Describe the bug

As above. Never seems to trigger.

To Reproduce

As described in #4289, after it was closed, this seems to be broken again. I'm at 6.1.1-canary-2. I'm using the example from the readme.md in my _app.js (in componentDidMount()). Successfully using Router.events though.

UPDATE:
Put this in _app.js (from readme.md):

Router.beforePopState(({ url, as, options }) => {
      console.log('state popped')
      if (as !== "/" || as !== "/other") {
        // SSR-render the specified location. (Should 404)
        window.location.href = as;
        return false;
      }

      return true;
    });

click Links or run Router.push() on other pages / in component. Routing executes as expected, but 'state popped' never triggers.

Expected behavior

Expecting 'state poppes' to be logged to console.

## Screenshots
-

System information

## Additional context
-

Most helpful comment

Why was this issue closed?

All 26 comments

馃 going to close this as there's nothing in the template filled out. Please provide a clear and concise reproduction, best in a GitHub repository.

Sorry! Managed to post this empty at first, somehow... Have edited this now.

Please add a minimal reproduction.

updated original post. hope this clarifies.

I've encountered this issue too. I also registered listener in onRouteChangeStart but it fired as expected. I just need to intercept the url change and is there an alternative way to do this? My next.js version is 6.0.3.

Same behaviour found also on _app.js

+1. I'm having the same issue.

@jsve Please add a full, but minimal reproduction example.

Going to close this.

So it's working in the new canary?

@jsve we can't tell, since we still haven't an example to reproduce this.

I looked through several of the other (accepted) bug reports and I think my supplied example is just as descriptive as those. What exactly is it that is not clear? Seems like at least 7 other people are able to reproduce this...

Why was this issue closed?

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history.back() or history.forward() in JavaScript).

Source

why was this issue closed? I 'm having same issue.

To fully explain, @HaNdTriX's comment says it all. The reproduction says "click links" or use "Router.push", but popstate is only triggered when using the back button of your browser. When using the back button everything works fine.

@HaNdTriX and @timneutkens are correct.

I believe the documentation could be _much_ clearer on what is going on, and the Zeit-representatives could be a bit more reasonable in their (now deleted) responses. However, this is not a bug.

believe the documentation could be much clearer on what is going on

Pull requests are always welcome to improve the docs 馃檹

their (now deleted) responses

I don't see anything being deleted though 馃

I'll try to explain more in the future 馃憤

why was this issue closed? I 'm having same issue.

Then I want to enter a route, do some judgment, return the ture release, return false interception, what should I do?

I am not sure what you are trying to do. But you can always use React for these kind of things:

Example

The following example implements a Redirect component similar to the react router one.
It reacts to route changes by using an layoutEffectHook.

components/ClientRedirect.js

import { useLayoutEffect } from 'react'
import { useRouter } from 'next/router'
import PropTypes from 'prop-types'

const ClientRedirect = ({ from, to, children }) => {
  // Get the router by hook
  const { route, replace, push } = useRouter()

  // We use useLayoutEffect here in order to react
  // to route changes before the browser has a chance 
  // to paint anything.
  useLayoutEffect(() => {
    if (route === from) {
      // Here we are changing the route to the new route 
      // without adding a history entry. Use push if you 
      // want to add an history entry.
      replace(to)
    }
  }, [route, from, to])

  // Return children incase you want to wrap this component
  return children || null
}

ClientRedirect.propTypes = {
  from: PropTypes.string.isRequired,
  to: PropTypes.string.isRequired
}

export default ClientRedirect

Please not that this code was created to illustrate the point of this issue, not for production usage.

// Somewhere in my app

export default () => (
   <div>
       <ClientRedirect from='/' to='/about' />
       <h1>Hello!</h1>
   <div>
)

https://github.com/zeit/next.js/#router-events

  • routeChangeStart(url) - Fires when a route starts to change
  • routeChangeComplete(url) - Fires when a route changed completely
  • routeChangeError(err, url) - Fires when there's an error when changing routes
  • beforeHistoryChange(url) - Fires just before changing the browser's history
  • hashChangeStart(url) - Fires when the hash will change but not the page
  • hashChangeComplete(url) - Fires when the hash has changed but not the page
componentDidMount() {
  Router.events.on('routeChangeStart', url => {
    this.props.showConfirmDialog('Are you sure?');
    throw new Error('this works');
  });
}

+1 on this bug

// _app.js
componentDidMount() {
    Router.events.on('routeChangeComplete', () => {
      console.log('complete');
    })

    Router.beforePopState(({url, as, opts}) => {
      console.log('_app.js beforePopState');
      console.log(url, as, opts);
      return true;
    });

    Router.events.on('routeChangeStart', url => {
      console.log('start');
    });
}

question: beforePopState cannot listen to route jumps implemented by Link

componentDidMount() {
    Router.events.on('routeChangeStart', (url) => {
      alert('route changes');
    });
    Router.beforePopState(({ url, as, opts }) => {
      alert('before pop state');
      return true;
    });
  }

Hi can I ask why my router.beforepopstate is not firing at all..?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesselee34 picture jesselee34  路  3Comments

olifante picture olifante  路  3Comments

irrigator picture irrigator  路  3Comments

ghost picture ghost  路  3Comments

swrdfish picture swrdfish  路  3Comments