Next.js: "No router instance found." error when setting Router.beforePopState in pages/_app.js

Created on 7 May 2018  路  8Comments  路  Source: vercel/next.js

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

Router.beforePopState should be easy to set. The code should reside in pages/_app.js with client-side only guard since it should be run on client only once.

Current Behavior

I put up an example repository here.

Server-side went ok without an error, but browsers complain with the following.

No router instance found.
You should only use "next/router" inside the client side of your app.

Error: No router instance found.
You should only use "next/router" inside the client side of your app.

    at throwIfNoRouter (http://localhost:3000/_next/static/commons/main.js:7835:11)
    at Object.SingletonRouter.(anonymous function) [as beforePopState] (http://localhost:3000/_next/static/commons/main.js:7799:5)
    at Object.<anonymous> (http://localhost:3000/_next/-/page/_app.js:2819:55)
    at Object../pages/_app.js (http://localhost:3000/_next/-/page/_app.js:2955:30)
    at __webpack_require__ (http://localhost:3000/_next/static/commons/manifest.js:715:31)
    at fn (http://localhost:3000/_next/static/commons/manifest.js:118:20)
    at Object.1 (http://localhost:3000/_next/-/page/_app.js:2962:18)
    at __webpack_require__ (http://localhost:3000/_next/static/commons/manifest.js:715:31)
    at webpackJsonpCallback (http://localhost:3000/_next/static/commons/manifest.js:26:23)
    at http://localhost:3000/_next/-/page/_app.js:5:7

Steps to Reproduce (for bugs)

Example repository

Context

See "Expected Behavior" above.

Your Environment

| Tech | Version |
|---------|---------|
| next | 6.0.0 |
| node | 10.0.0 |
| OS | macOS High Sierra 10.13.4 |
| browser | Google Chrome 66.0.3359.139 |
| etc | |

Most helpful comment

@peacefullybound Well at first i did have the same problem as yours, and after move that code to componentDidMount in _app.js the error disappear, but unfortunately it's still not working as well without any error informed on the dev console, here is my componentDidUpdate code:

componentDidMount() {
    Router.beforePopState(({ url, as: asUrl, options }) => {
        console.log('why you never hit me :( tho')
    if (asUrl !== '/dashboard') {
            console.log('should redirect to 404 but it didnt')
        window.location.href = asUrl
        return false
    }
    return true
    })
}

my next version is 6.0.3, please share how you solved this issue

All 8 comments

Regardless of my expectation, I want to know if I miss something, or more proper way of setting Router.beforePopState. Thanks in advance.

I fixed the issue by moving the usage of Router.beforePopState into App#componentDidMount. I'll close this. Thanks for any concerns.

hi @peacefullybound i did move it to componentDidMount lifecycle but unfortunately it still didnt work whenever i changed the route, any thought tho?

What do you mean exactly by "still didnt work"? @afganhalbana I think you should open a separate issue if it's not the same as "No router instance found."

@peacefullybound Well at first i did have the same problem as yours, and after move that code to componentDidMount in _app.js the error disappear, but unfortunately it's still not working as well without any error informed on the dev console, here is my componentDidUpdate code:

componentDidMount() {
    Router.beforePopState(({ url, as: asUrl, options }) => {
        console.log('why you never hit me :( tho')
    if (asUrl !== '/dashboard') {
            console.log('should redirect to 404 but it didnt')
        window.location.href = asUrl
        return false
    }
    return true
    })
}

my next version is 6.0.3, please share how you solved this issue

@afganhalbana Facing the same issue, any luck with it?

hihi

I solve my problem by checking first if Router wasn't undefined.
const pathname = Router ? Router.pathname : ''

The solution was inconsistent though, as sometimes the error came back. So a better option is to use withRouter and check on the props for the current pathname. Example

import {withRouter} from 'next/router'
withRouter(MyComponent)

const MyComponent = ({ router: { pathname } }) => <div>{ pathname }<div>
Was this page helpful?
0 / 5 - 0 ratings