Lucdabomb
Lucdabomb

Reputation: 261

Cannot set headers after they are sent to the client with res.writeHead()

I am trying to redirect a user to the login if he isn't authenticated. I hardcoded the jwt for now. This works, but I only get an error saying Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.

Since the function works I don't know what is wrong and couldn't really find an answer to it either. This is my code for reference:

function redirectUser(ctx, location) {
  if (ctx.req) {
    ctx.res.writeHead(302, { Location: location });
    ctx.res.statusCode = 302;
    ctx.res.setHeader(302, location);
    ctx.res.end();
    return { props: {} };
  } else {
    Router.push(location);
  }
}

// getInitialProps disables automatic static optimization for pages that don't
// have getStaticProps. So article, category and home pages still get SSG.
// Hopefully we can replace this with getStaticProps once this issue is fixed:
// https://github.com/vercel/next.js/discussions/10949
MyApp.getInitialProps = async (ctx) => {
  const jwt = false;

  // Calls page's `getInitialProps` and fills `appProps.pageProps`
  const appProps = await App.getInitialProps(ctx);
  // Fetch global site settings from Strapi
  const global = await fetchAPI("/global");

  if (!jwt) {
    if (ctx?.ctx.pathname === "/account") {
      redirectUser(ctx.ctx, "/login");
    }
  }

  // Pass the data to our page via props
  return { ...appProps, pageProps: { global } };
};

Any help would be much appreciated.

Upvotes: 0

Views: 3336

Answers (1)

Rahul Singh
Rahul Singh

Reputation: 710

The error "Error: Can't set headers after they are sent." means that you're already in the body, but some other function tried to set a header or statusCode. In your case it is the function ctx.res.setHeader(302, location); that's causing the issue.

After writeHead, the headers are baked in and you can only call res.write(body), and finally res.end(body).

You do not need to use setHeader when you are already using the writehead method.

Read here more about the writehead

So your redirectUser could be like :


function redirectUser(ctx, location) {
  if (ctx.req) {
    ctx.res.writeHead(302, { Location: location });
    ctx.res.end();
    return { props: {} };
  } else {
    Router.push(location);
  }
}

Upvotes: 2

Related Questions