vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.11k stars 27.01k forks source link

Docs: CORS Middleware example uses deprecated/non-working NextResponse.json() #70406

Open alexandros-megas opened 1 month ago

alexandros-megas commented 1 month ago

What is the documentation issue?

The page for Middleware demonstrates how to use middleware to implement CORS, setting the appropriate headers for OPTIONS requests, and also adding CORS headers to other responses.

https://github.com/vercel/next.js/blob/16ffa0323c09bf02aa77923c6f7bda8ea74c9f98/docs/02-app/01-building-your-application/01-routing/14-middleware.mdx?plain=1#L380

If you run this example, you will get the following error when making an OPTIONS request:

[Error: A middleware can not alter response's body. Learn more: https://nextjs.org/docs/messages/returning-response-body-in-middleware]

This page tells you that due to this being an anti-pattern, it's not allowed to create your own response body in middleware, and instead you should redirect/rewrite.

I was able to work around this, by creating my own endpoint, pages/api/cors-preflight.ts with the following:

export default async function handlePreflight (_req, res) {
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader('Access-Control-Allow-Origin', 'http://mydomain.com');
  res.setHeader('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT');
  res.setHeader('Access-Control-Allow-Headers', 'header-1, header-2, ...');
  res.status(200).end();
}

and then replacing NextResponse.json(...) with the following 2 lines:

    const nextUrl = `${allowedOrigin}/api/cors-preflight`;
    return NextResponse.rewrite(nextUrl, { headers: corsOptions });

Is there any context that might help us understand?

I think the issue is pretty thoroughly explained. The docs should be updated to reflect the correct use of middleware.

Does the docs page already exist? Please link to it.

https://nextjs.org/docs/pages/building-your-application/routing/middleware#cors

samcx commented 1 month ago

@alexandros-megas I'm not getting this error when copy-pasting the snippet from the docs. To clarify, NextResponse.json is not drepecated.

Can you create a :repro: so we can take a look?