I am using React and Next.js and trying to redirect a user from a page when the data for that page is not available using Router.push('/another-page')
.
To do this I am checking for a status code in getInitalProps
and applying a conditional. It looks like this:
const statusCode = action.currentArticle ? 200 : 404
if (isServer) res.statusCode = statusCode
if (statusCode === 404) {
Router.push('/')
}
The status code is being set properly and it makes it inside the conditional, at which point I am greeted with this error: No router instance found. You should only use "next/router" inside the client side of your app.
Actually, I am getting the same error no matter WHERE in the component's lifecycle events I try to redirect, and am getting little info online about this error.
The pattern of redirecting from getInitalProps
can be seen in this next.js wiki: HERE
Any ideas on why this error is occurring or how to fix it are much appreciated ;)
With Next.js (and any universal react rendering) your code is executing in two different environments. First in Node (on the server) and then in a browser. Next does some work to provide unified functions that run in both these environments but they're very different. Next can't and doesn't keep this from you. It seems like you just loaded a page in your browser but here's a little more detail on what's really going on…
On the client/browser:
On the server/Node:
render()
function is called with the request and response objects.getInitialProps
and passes in the request/response.renderToString()
is called which calls the following React lifecycle methods:
constructor()
componentWillMount()
render()
^ This is Node. You can't access window
, you don't have fetch
, and you can't use the Next Router. Those are browser things.
Back on the client:
render()
is run which associates the downloaded HTML (the DOM) with a React virtual DOM. The following React lifecycle methods will run:
constructor()
componentWillMount()
render()
componentDidMount()
^ This is the browser. You have window
, you have fetch
, you can use the Next Router. Now you don't have the Node request/response but that seems to catch people up less.
Ref: Component lifecycle
The way works like @Shi said, but there is not server
in getInitialProps. Instead of that, there should check window
:
getInitialProps({res}){
if(typeof window === 'undefined')
res.redirect('/');
else
Router.push('/');
}
You can redirect from getInitialProps()
like this:
import Router from 'next/router'
static getInitialProps = (ctx) => {
// On server
if(typeof window === 'undefined'){
res.writeHead(302, {location: '/dashboard'})
res.end()
} else {
// On client
Router.push('/dashboard')
}
return {}
}
See https://github.com/zeit/next.js/issues/649
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With