sindresorhus / ky

🌳 Tiny & elegant JavaScript HTTP client based on the Fetch API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Content-length header is sent to the server with empty value in Next.js 13 route handler.

wa12rior opened this issue · comments

commented

I'm using nextjs 13 with new app router and next-auth. My authorize method in CredentialsProvider looks like this:

async authorize(credentials) {
        if (!credentials) {
          return null;
        }

        try {
          const data = await loginUser({
            email: credentials.email,
            password: credentials.password,
            redirect: false,
          });

          const user: AppUser = {
            ...
          };

          return user;
        } catch (error) {
          console.error(error);
          return null;
        }
      },

Here is the body of the loginUser method

export const loginUser = async (values: LoginParams) => {
  const loginUrl = 'login';

  return await ky
    .post(loginUrl, {
      json: values,
      prefixUrl: prefixUrl,
    })
    .json<TokenUserResponse>();
};

And server gets empty request payload because header content-length is empty ("").
When I add it manually it suddenly works.

headers: { 'content-type': 'application/json', 'content-length': JSON.stringify(values).length + '' },

Does someone knows why that is happening?

commented

Anyone?

don't know the exact reason I faced the same issue.
the json payload sent to one of the backend service from route handler was empty.
I did headers: { 'content-type': 'application/json', 'content-length': JSON.stringify(values).length + '' },
and it worked for me too.

It's definitely has to do something related to nextjs's wrap around the fetch (to handle cache) which is globally available.
But thanks for your workaround here.

commented

@mabdullahadeel No problem.
Although this is workaround I found a way to do it in beforeRequest hook to avoid unnecessary code duplication.

hooks: {
    beforeRequest: [
      (request, options) => {
        request.headers.set('Content-Type', 'application/json');
        if (options.body) {
          request.headers.set('Content-Length', options.body.length);
        }
      },
    ],
  },