Next.js: Using writeHead to redirect in `getServerSideProps` fails on Safari

Created on 2 May 2020  路  16Comments  路  Source: vercel/next.js

Bug report

Describe the bug

Using a Next Link component to route to a page where there is a check to see if a cookie is defined, and if so to redirect the user seems to fail on Safari.

// login.js

export async function getServerSideProps(ctx) {
  // Nookies parse cookies function to get the current cookies
  const cookies = parseCookies(ctx);

  if (cookies.token) {
    ctx.res.writeHead(303, { Location: "/admin" });
    ctx.res.end();
  }

  return { props: {} };
}

The Link component points to /login and is in the global navigation.

It seems that clicking on this on Safari changes the current path to /login however nothing happens.

On Chrome it seems that the page is properly redirected to /admin should the token cookie be defined.

Expected behavior

res.writeHead() behaves the same on Safari as it does on Chrome.

System information

  • OS: macOS Catalina 10.15.4 (19E287)
  • Browser (if applies) Safari Version 13.1 (15609.1.20.111.8)
  • Version of Next.js: 9.3.5
  • Version of Node.js: v14.0.0
bug needs investigation

Most helpful comment

I think the same problem occurs with FireFox. I've followed this blog post to implement the same functionality, but a different way:

https://sergiodxa.com/articles/redirects-in-next-the-good-way/

All 16 comments

I think the same problem occurs with FireFox. I've followed this blog post to implement the same functionality, but a different way:

https://sergiodxa.com/articles/redirects-in-next-the-good-way/

Yeah I noticed it happened there too.

~@joaogranado wondering if there's a new solution to handle this with Next 9.3 new routing stuff with getServerSide, ~

~I'd rather not use getInitialProps anymore~

EDIT

Looks like getIntialProps is just used for the server side. I guess could replace it with getServerSideProps and still handle the routing bits on the client side.

image

Happened to me too, here is the console error log

The line in router.js that the error comes from is https://github.com/zeit/next.js/blob/0d05904552dc4ba517ec158446c175d72a78814f/packages/next/next-server/lib/router/router.ts#L493

But that's just where it gets thrown. This is where it originates:

https://github.com/zeit/next.js/blob/0d05904552dc4ba517ec158446c175d72a78814f/packages/next/next-server/lib/router/router.ts#L134

The error being caught there is SyntaxError: The string did not match the expected pattern. likely because the client was expecting JSON but received HTML (as explained here).

But I don't know why setting the code property of the SyntaxError is readonly. If you create a SyntaxError in the console and try to set the code, it works fine.

Setting the code throws an error because it's running in strict mode.

In a production build, the error is caught and you are shown the error page. This differs from the behavior exhibited by Chrome where the redirect works after Next triggers a full page reload.

Screen Shot 2020-05-20 at 10 44 19 AM

Same here.
I just replaced the Next Links with HTML anchor tags where the pages using res.writeHead().

i can confirm this issue on Safari and Edge as well. server-side redirections triggers the error page.

One workaround is to replace Link with a but this downgrades experience for all browsers

Can confirm as well, happens only in production and in Safari on iOS 13.5.1.
Unfortunately, replacing the Link component by Next.js is not an option for me.

Does anybody know the status of this bug?

I think the same problem occurs with FireFox. I've followed this blog post to implement the same functionality, but a different way:

https://sergiodxa.com/articles/redirects-in-next-the-good-way/

Thanks for sharing this, was able to work around this issue with that method.

Looks like this also affects Router.push() when you push some page that return a 30x

This issue should be fixed with this PR that was just merged into canary: https://github.com/vercel/next.js/pull/16051

Hi, as mentioned above this should be resolved by https://github.com/vercel/next.js/pull/16051 now and we are also aiming to streamline redirecting in these functions with https://github.com/vercel/next.js/discussions/14890.

I'm going to close this since it should be addressed, if you are still having problems with this please reply with additional info

Was this page helpful?
0 / 5 - 0 ratings