Repository navigation
Return redirect from getServerSideProps #11281
|
For example to redirect from
Would be cool to be able to do this easily, for example by Or is it possible to do such thing now? I could not find any way except maybe handling both cases manually and doing |
Replies: 18 comments 43 replies
|
Would be nice. In the mean time we use a custom server.ts and have a redirect middleware there. |
|
I'm also interested in the answer! It's something that with |
|
Just encountered this myself today. +1 for supporting redirects that get handled on the server and client |
|
This would be super helpful to be able to do. I too need to redirect a non-logged-in user from /dashboard to /login, or a logged-in user from / to /dashboard. Any quick workaround would be appreciated :) |
|
I think a more generic solution could be beneficial. In the code below, you can see how the A possible solution could be an For example, the developer sets a prop in This would provide a lot of flexibility to the developer. |
|
I'm doing this for now. See below. Visiting
When it's client-side routing the request to getServerSideProps contains a Warning: This was edited for the sake of the example so there might be a couple of syntax problems.
Might have to tweak that slightly for your use-case but you get the idea. |
|
What about something like this: import { NextPageContext } from "next";
import Router from "next/router";
export type NextRedirectOptions = {
to: string;
ctx: NextPageContext;
};
export const nextRedirect = async (options: NextRedirectOptions): Promise<any> => {
if (typeof window === "undefined") {
options.ctx.res.writeHead(307, { Location: options.to });
options.ctx.res.end();
} else {
Router.replace(options.to);
}
return new Promise(() => {});
};and TestPage.getInitialProps = async ctx => {
const isAuthenticated = true/false;
if (!isAuthenticated) {
return nextRedirect({ ctx, to: "/login" });
}
const data = await fetchStuff();
return data;
};This way our component won't get rendered if we redirect in |
|
It would be nice, if returning |
|
The with-iron-session and auth0 examples have been updated to do redirects from within I'm not convinced that this is the best pattern. If you watch the network traffic, the browser follows the redirect and requests the page, but it was an AJAX request so the URL doesn't change. It just seems like Next is smart enough to figure out what's going on and makes another request for the page that the AJAX request was redirected to. It's very inefficient and perhaps only works due more to happenstance than intent. But I'm still learning. |
|
I submitted a PR to add the redirect functionality proposed in the initial post: export async function getServerSideProps() {
return {
props: {},
redirect: '/',
}
} |
|
I found adding the custom When a redirect is needed, just throw a redirect error. By this means you don't need to include additional props for the component. export const getServerSideProps: GetServerSideProps = async () => {
...
if (data === null) throw new RedirectError(302, '/')
...
}in my _error.tsx ErrorPage.getInitialProps = async function ({ res, err }) {
const props = { statusCode: 500 }
if (!res) return props
if (err instanceof PageError) {
props.statusCode = err.statusCode
res.statusCode = err.statusCode
if (err instanceof RedirectError) {
res.writeHead(err.statusCode, { Location: encodeURI(err.url) })
res.end()
}
} else {
console.error(err)
}
return props
}And I have 2 types of error export class PageError extends Error {
statusCode = 500
}
export class NotFoundError extends PageError {
statusCode = 404
}
export class RedirectError extends PageError {
url: string
constructor(code: number, url: string) {
super()
this.statusCode = code
this.url = url
}
} |
|
I ended up using this solution to show an error page when a user tries to access a blog post that doesn't exist. It's not pretty but it gets the job done for now: export async function getServerSideProps(ctx: NextPageContext) {
// get article data from contentful
const { article } = ctx.query
const post = await contentful.fetchNewsPostBySlug(article)
// if no post is found, set error prop and show error page
if (!post) {
const props = {
error: true,
}
return {
props,
}
}
// code to return article props if they exist
}
// in my component:
interface Props {
post: PostData
error?: boolean
}
export default function NewsArticlePage({ post, error }: Props) {
if (error) {
return <ErrorPage />
}
// code to return page component if post data exists
} |
|
So what is the solution for redirecting on both server and client using getServerSideProps that woks correctly. Any luck on this? |
|
For Short β¨π I've got example of Next Docs: π link you have to put code below inside your getServerSideProps return {
redirect: {
destination: '/',
permanent: false,
},
}It works for me, hopefully it would help π―β¨ |
|
Can I get the props after redirection? After the redirect, I am trying to get the props on the "auth-page". The props object is empty. |
|
Take a look at: https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#redirect export async function getServerSideProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
},
}
}
return {
props: {}, // will be passed to the page component as props
}
} |
|
It works from SSR but does not work when calling getServerSideProps() from the client side. |
Opened a RFC here: #14890