RFC: Returning redirects from getServerSideProps / getStaticProps #14890
Replies: 38 comments 66 replies
-
Not sure if it's possible, but could we somehow get an access to the request in I'm referring to this comment: #11346 (comment) |
Beta Was this translation helpful? Give feedback.
-
It's important to make sure the solution is TypeScript compatible. Looks like it can, assuming this change: next.js/packages/next/types/index.d.ts Lines 117 to 126 in 38bd1a0 ⬇️ + type SomeStandardRedirectConfigType = {...}
export type GetServerSidePropsResult<P> = {
props: P
+ } | {
+ redirect: SomeStandardRedirectConfigType
} So when the result includes BTW what will Next do when it sees both fields returned from |
Beta Was this translation helpful? Give feedback.
-
Just wondering, why 307/308? It seems like there isn't that much support in the older versions of Chrome and Firefox: https://caniuse.com/#search=308 |
Beta Was this translation helpful? Give feedback.
-
Are we contemplating the possibility of allowing cookies to be forwarded from redirects? That would be pretty useful for keeping authentication alive, for instance. |
Beta Was this translation helpful? Give feedback.
-
@timneutkens this is great.
|
Beta Was this translation helpful? Give feedback.
-
@timneutkens this feature looks nice and useful, thank you. I have a question about
Could you explain more what do you mean? A client-side transition (changing a route on the client-side) doesn't look SEO-friendly. Let me know if I'm wrong. |
Beta Was this translation helpful? Give feedback.
-
How Vercel redirect login to dashboard without showing any part of login page? It’s seem to me that they use server side redirect but I’m not sure. If it’s really server sided how can that page be so fast like it is static page? I’ve also opened discussion here on swr repo |
Beta Was this translation helpful? Give feedback.
-
I'm interested in this RFC to automatically opt-in to preview mode by redirecting to my It feels like this would be possible with the current proposal. Is there any ETA? My only workaround for now is to perform this from the client side, which isn't optimal UX-wise. I had opened a question about that but didn't get much feedback so far. But after reading this RFC and #11346 I came to the conclusion it can only be done from the browser, until proper redirects can be done from |
Beta Was this translation helpful? Give feedback.
-
Hi, i think these bugs may be related too; these happens on Edge and Safari and when you try route to a new url that return a |
Beta Was this translation helpful? Give feedback.
-
Is there any movement on this outside of this discussion? Been running into some breaking issues surrounding this in Safari. Happy to jump in and help if there's already a branch started somewhere! |
Beta Was this translation helpful? Give feedback.
-
Is there a suggested solution for this in the meantime? Something that isn't super hacky, doesn't involve creating a custom server and works on both the client and the server? Another question I had was, if I add |
Beta Was this translation helpful? Give feedback.
-
I wonder, would that somehow allow us to return 404 status code from getStaticProps (with |
Beta Was this translation helpful? Give feedback.
-
How about throwing errors instead of returning objects? For example: import { RedirectResponse, ErrorResponse, NotFoundResponse } from 'next';
export default function HomePage() {
return <>Hello World</>
}
export async function getServerSideProps({params}) {
const item = await getData(params.id)
if(!item) {
throw new NotFoundResponse();
}
if(item.slug) {
throw new RedirectResponse('/somewhere-else', { permanent: false });
}
if(item.published === false) {
throw new ErrorResponse(403);
}
return {
props: {
item
}
}
} This makes it also possible to throw these errors in nested functions, like in the 'getData' function for example. Furthermore, TypeScript can probably autocomplete a lot more using these kind of classes. |
Beta Was this translation helpful? Give feedback.
-
What do you think of Next provide an shortcut function just to make the code cleaner? function redirect(to, permanent = false) {
return {
redirect: {
permanent,
destination: to,
},
}
} or function redirect(to, options = { permanent: false }) {
const { permanent } = options
return {
redirect: {
permanent,
destination: to,
},
}
} export async function getServerSideProps({ params }) {
const item = await getData(params.id)
if (!item) {
return redirect("/somewhere-else", true)
}
return {
props: {
item,
},
}
} or export async function getServerSideProps({ params }) {
const item = await getData(params.id)
if (!item) {
return redirect("/somewhere-else", { permanent: true })
}
return {
props: {
item,
},
}
} export async function getStaticProps({ params }) {
const item = await getData(params.id)
if (!item) {
return redirect("/somewhere-else")
}
return {
props: {
item,
},
}
} |
Beta Was this translation helpful? Give feedback.
-
Also, when fallback is set to "custom", it can run getServerSideProps. So, it supplies full customization. I don't know the possibility of it. edit1: Is it possible to make getStaticProps with HTTP redirect? I desire make an site is render a page from db or redirect. When using getServerSideProps option, it can't benefit from cache ( generated html ). edit2: [[...slug]].tsx
It seems very good, thank you |
Beta Was this translation helpful? Give feedback.
-
It seems difficult to implement it when API calls are chained... export async function getServerSideProps({query}){
const documents = await getDocuments(query.id)
const users = await getUsers(documents)
const kittens = await getKittens(users)
return ({
props : {
documents,
users,
kittens
}
}) A method to implement server side (e.g. Axios interceptors) would be more convenient ! import {Redirect} from 'next/server-side'
// maybe : {Router} from 'next/server-side'
import {LOGIN} from '@constants/routes'
// [...]
// Axios interceptor
static responseError(error) {
if (error?.response?.status === 401){
Redirect(LOGIN)
}
} |
Beta Was this translation helpful? Give feedback.
-
This has been implemented right? Which version of next.js does this ship into? Also, in the initial proposal in this discussion, what did you mean by: |
Beta Was this translation helpful? Give feedback.
-
Canary has stable support now: #18282
…On Mon, Oct 26, 2020 at 9:28 PM Karl Horky ***@***.***> wrote:
Next.js 9.5.4 has *unstable* support for it:
https://github.com/vercel/next.js/releases/tag/v9.5.4
See how to use it now:
https://github.com/vercel/next.js/pull/16642/files#diff-318f35e639c875557159a9297bd3415458e884208be91285a622f9484395aa83R28-R33
Once stable support is released, I guess it will be written about on the
Next.js Blog: https://nextjs.org/blog
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#14890 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB2UDXSJQASJTBZ62WTJF7LSMXSW3ANCNFSM4ORVK2AQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Ok, so I opened up an Issue. |
Beta Was this translation helpful? Give feedback.
-
Open PR to add this to documentation #18626 |
Beta Was this translation helpful? Give feedback.
-
With next.js v10 it is now possible to use redirect with But even with this feature it seems that next.js lacks routes middlewares (or route guards) to handle authentication abstraction. Does someone has an example of route auth in next.js, I'm new to next.js and I've seen a lot of different patterns and I can't figure out which one are good or bad. For now the best option I found is to duplicate code in each route: // /app/dashboard.tsx
...
export async function getServerSideProps() {
const isAuth = auth({ roles: ['user'] })
if (!isAuth) {
return {
redirect: {
permanent: false,
destination: '/login',
},
}
}
}
// /app/settings/user.tsx
...
export async function getServerSideProps() {
const isAuth = auth({ roles: ['user', 'admin'] })
if (!isAuth) {
return {
redirect: {
permanent: false,
destination: '/login',
},
}
}
}
// /app/settings/account.tsx
...
export async function getServerSideProps() {
const isAuth = auth({ roles: ['admin'] })
if (!isAuth) {
return {
redirect: {
permanent: false,
destination: '/login',
},
}
}
} Would be nice to have middleware system so I could just compose middleware based on route paths, (as @StarpTech said in #11822) E.g.: Router.guards.add('/app/*, [authMiddleware({ roles: ['user']) }]);
Router.guards.add('/app/settings/*, [authMiddleware({ roles: ['admin']) }]); |
Beta Was this translation helpful? Give feedback.
-
Trying to migrate to SSR redirects we're facing some issues. We have a "auth" middleware that will redirect users to context.res.writeHead(302, { Location: '/login', 'set-cookie': 'some-value-that-clears-session' });
context.res.end(); With this, we are also clearing user's session cookie by adding the |
Beta Was this translation helpful? Give feedback.
-
For anyone interested in consistent authentication "middleware" using the new redirect, here's a pattern that I've adopted. Not entirely sure how I feel about this abstraction for the long term but it works okay for what I need at the moment.
export const withAuthentication = (getServerSidePropsFn: GetServerSidePropsFn) => ctx => {
const token = cookies(ctx)?.token;
if (!token) {
return {
redirect: {
permanent: false,
destination: "/log-in"
}
}
}
return getServerSidePropsFn({ token });
}
export const getServerSideProps = withAuthentication(async ({ token }) => {
return {
props: {
// ...
}
}
}) If you want, you could get fancy and create a function to chain these together to be more like true middleware. e.g. (untested code, just a general idea that comes to mind) const middleware = chain => ctx => {
chain[0](ctx, () => {
if (chain.length > 1) {
middleware(chain.slice(1))(ctx);
}
})
}
const withAuthentication = (ctx, next) => {
// do something with context
next();
};
export const getServerSideProps = middleware([withAuthentication, withSomethingElse, finalGetServerSideProps]); In any case, in my opinion this is just a utility that Next.js is not responsible for supporting and does not belong in the Next.js library. (edited for clarity) |
Beta Was this translation helpful? Give feedback.
-
What about rewrites ? My use case is with slugs :
I wish I could do it like this :
|
Beta Was this translation helpful? Give feedback.
-
I'm currently using next v10.0.4 and trying the new getServerSideProps with returning a redirect as shown below. It was my understanding that this would automatically do a redirect to a route in my app called /somewhere-else. But instead, this is calling my custom 404 page. Did I miss something? Do I need to handle inside my 404 page? If so, what do I use to know what caused 404?
|
Beta Was this translation helpful? Give feedback.
-
I don't know in what version Vercel added this...but.. if all you want is to redirect to a 404 page....you can simply do this.. export async function getServerSideProps() { it doesn't redirect... you don't get a 302 (redirect status)...you just render 404 page, with original url and all! 🎉🥳 |
Beta Was this translation helpful? Give feedback.
-
It would be nice if this redirect was also verified in '_app.js' getInitialProps. Some global redirects (like authorization) can enjoy this! |
Beta Was this translation helpful? Give feedback.
-
Hard to tell from the discussion; what's the current status of this feature? My usecase is that I've got a blog:
I'm statically-rendering these posts with
I've tried with both |
Beta Was this translation helpful? Give feedback.
-
This has been released, sorry! I forgot to post back and close this discussion 👍 https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation |
Beta Was this translation helpful? Give feedback.
-
This has been released:
Original RFC
After
getServerSideProps
andgetStaticProps
were introduced there was a lot of feedback of users trying to do redirects (see list of discussions below mentioning redirects). Even withgetInitialProps
this issue has come up quite a bit given that you had to manually detect the server/client-side using eitherres
and ending the response orRouter.push
(using the client-side Next.js router)This would generally looks something like this:
Some people wrote helper libraries and articles for this behavior
Proposal
Ideally we'd provide a behavior to allow redirection as it'll avoid code duplication is user code and make it significantly easier to do a server-side or client-side redirect to a page. This could be driven by
getStaticProps
/getServerSideProps
through returning an extraredirect
key in both methods.The
redirect
key would allow for settingpermanent
totrue
orfalse
which will use the 308 and 307 status code respectively (they're the new equivalent of 301 / 302)The
redirect
key would allow for setting thedestination
of where you want to goAn example of how this would look:
When using static generation with the
fallback: true
behavior you might also want to redirect to another page when the page does not exists, hence why redirect might be useful there also:When moving between pages using
next/router
andnext/link
and adestination
matches a route in the Next.js application a client-side transition happens. If it did not match a full transition happens.Beta Was this translation helpful? Give feedback.
All reactions