Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Missing information about redirecting #11797

Closed
nahtnam opened this issue Apr 9, 2020 · 13 comments
Closed

Docs: Missing information about redirecting #11797

nahtnam opened this issue Apr 9, 2020 · 13 comments

Comments

@nahtnam
Copy link

nahtnam commented Apr 9, 2020

Feature request

Is your feature request related to a problem? Please describe.

I've been looking through the docs and I can't seem to find any information on how to redirect. There used to be a wiki page but that got deleted, and so the only information I could find are in GitHub issues.

  1. So it seems okay to redirect in getInitialProps, however that is being deprecated in favor of getServerSideProps. Is it safe to redirect in there?
  2. However, @Timer said that you shouldn't redirect in getInitialProps using the client-side router (here). Which makes the method that was mentioned in the original wiki page incorrect.

So what is the best way to redirect in the current version of next? Looking at zeit.co it looks like its being done in getInitialProps but I can't be sure. If I had to venture a guess you should do it in getServerSideProps and useEffect in the function for client-side redirection.

Describe the solution you'd like

A page that describes the recommended way to redirect on the server-side and/or client side.

Describe alternatives you've considered

N/A

Additional context

N/A

@nahtnam
Copy link
Author

nahtnam commented Apr 16, 2020

Bump

@tranlehaiquan
Copy link

+1 for this

@zenflow
Copy link
Contributor

zenflow commented Apr 29, 2020

So it seems okay to redirect in getInitialProps, however that is being deprecated in favor of getServerSideProps

@nahtnam I don't believe that's exactly true.. From the Next.js Blog:

These improvements are API additions. All new functionality is completely backwards compatible and can be incrementally adopted. No deprecations are introduced and getInitialProps will continue to function as it currently does. We do encourage adopting these new methods on new pages and projects.

Anyways... +1.. Next.js should have a recommended (or even standard) way to do redirects.

@zenflow
Copy link
Contributor

zenflow commented Apr 30, 2020

Based on @Timer's enlightening comment (#4931 (comment)), I derived a nice clean abstraction that I want to share.

Define the Redirect component like this:

// lib/redirect.js
import { useRouter } from 'next/router'
import { useEffect } from 'react'

export function Redirect ({ to, action = 'push' }) {
  const router = useRouter()
  useEffect(() => {
    router[action](to)
  })
  return null
}

Use the Redirect component like this:

// pages/some-page.js
import { Redirect } from '../lib/redirect'

export default function SomePage {
  if (someCondition) {
    return <Redirect to="/some-other-page" />
  }
  return <p>Normal content...</p>
}

Note: It can be used deep within the component tree.

At first I was doing something more complex and less flexible, but I eventually realized that there's no need to mess with getInitialProps or getServerSideProps to handle redirects.

The only downside is (as with @Timer's example) we momentarily show the user a blank page. That could be replaced with a "Redirecting..." message but I don't think that is much nicer.

@zenflow
Copy link
Contributor

zenflow commented Apr 30, 2020

Happy to make a PR to add this to the documentation if maintainers deem this an acceptable way to do redirects.

@nahtnam
Copy link
Author

nahtnam commented Apr 30, 2020

I don't think this is proper though, if we have the ability to SSR, we shouldn't be showing a blank screen right? That would kill SEO

@Vinnl
Copy link
Contributor

Vinnl commented Apr 30, 2020

@zenflow Yeah, client-side redirects are nice and all, but ideally we'd have the server do an HTTP 301 redirect if it's the entry point, and the client either doing a client-side redirect on navigation, or even simply rewriting all links to the destination URL.

@nahtnam
Copy link
Author

nahtnam commented Apr 30, 2020

If I had to venture a guess, this is what the new redirect should be something like this, but is this the correct way to do it?

export default function Post() {
  useEffect(() => {
	Router.push('/signin')
  })
}

export async function getServerSideProps({ res }}) {
  res.writeHead(status || 302, { Location: '/signup' });
  res.end();
}

@tranlehaiquan
Copy link

tranlehaiquan commented Apr 30, 2020

If I had to venture a guess, this is what the new redirect should be something like this, but is this the correct way to do it?

export default function Post() {
  useEffect(() => {
	Router.push('/signin')
  })
}

export async function getServerSideProps({ res }}) {
  res.writeHead(status || 302, { Location: '/signup' });
  res.end();
}

I have tried that. It works fine sometimes. But in catch case, it not working well. Do you try it? I don't think it is the right way right now.

export default function Post() {
  useEffect(() => {
	Router.push('/signin')
  })
 return <div>something</div>
}

export async function getServerSideProps({ res }}) {
  try {
    const data = await fetchSomeData();
    return {props: { data }};
  } catch (err) {
    res.writeHead(status || 302, { Location: '/signup' });
    res.end();
    return {props: { }};
  }
}

@zenflow
Copy link
Contributor

zenflow commented May 7, 2020

Yeah, client-side redirects are nice and all, but ideally we'd have the server do an HTTP 301 redirect if it's the entry point, and the client either doing a client-side redirect on navigation, or even simply rewriting all links to the destination URL.

@Vinnl Yup, I agree that's the ideal. But since it's not clear how the ideal (client or server redirects as needed) can be possible...

For situations where we don't need SSR (e.g. redirect after login, redirect away from protected pages) we can use <Redirect>, which is just an abstraction on the suggested method of redirecting.

It's possible to render some "Redirecting..." screen instead of a blank page if you wish.

I think it's a good solution for when client-side redirects work for you.

That said, I'm still hoping we can have a unified way of doing redirects, which works seamlessly on both server & browser. (Technically a different issue from this one about documentation)

@timneutkens
Copy link
Member

Opened a RFC for redirecting here: #14890

@lachlanjc
Copy link
Contributor

There's docs for this at the end of this section: https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation

Can we close?

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants