In a Next.js app, you might want to redirect during the execution of getInitialProps()
.
For example, if somebody is trying to access a members-only page but is not logged in (by the way, make sure you're authenticating your users securely).
Client-Side vs. Server-Side Redirects in Next.js
Redirects in Next.js work more or less as you would expect them to. We only need to keep in mind that we have two ways of redirecting the user:
- Client-side redirects – If the user is accessing a page during client-side navigation, we'll use the Next.js'
Router
object to redirect him - Server-side redirects – If the user is accessing a page during server-side Rendering (SSR), we'll redirect via the appropriate HTTP response
Code example
Here's what this might look like in code:
pages/members-only.js
import Router from 'next/router'async function getInitialProps({ res, user }) {if (!user) {if (res) {// On the server, we'll use an HTTP response to// redirect with the status code of our choice.// 307 is for temporary redirects.res.writeHead(307, { Location: '/' })res.end()} else {// On the client, we'll use the Router-object// from the 'next/router' module.Router.replace('/')}// Return an empty object,// otherwise Next.js will throw an errorreturn {}}return { secretData: '...' }}function MembersOnlyPage({ secretData }) {return (<p>You should never see this if you're not logged in:{secretData}</p>)}MembersOnlyPage.getInitialProps = getInitialPropsexport default MembersOnlyPage
External Client-Side Redirects without Content Flashing in Next.js
If you want to do a client-side redirect to an external page, you can
use window.location
and a never-resolving promise to make sure that nothing gets rendered
while the redirect is taking place.
pages/flamingo.js
async function getInitialProps({ res, user }) {const targetURL = 'https://www.youtube.com/watch?v=11KaKhGAa3I' // 🦩if (res) {// On the server, we'll use an HTTP response to// redirect with the status code of our choice.// 307 is for temporary redirects.res.writeHead(307, { Location: targetURL })res.end()} else {// We'll redirect to the external page using// `window.location`.window.location = targetURL// While the page is loading, code execution will// continue, so we'll await a never-resolving// promise to make sure our page never// gets rendered.await new Promise((resolve) => {})}return {}}function FlamingoPage() {return <p>This should never get rendered</p>}FlamingoPage.getInitialProps = getInitialPropsexport default FlamingoPage