next.js
next.js copied to clipboard
Streaming API Responses Not Working on Vercel
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 20.6.0: Tue Feb 22 21:10:41 PST 2022; root:xnu-7195.141.26~1/RELEASE_X86_64
Binaries:
Node: 16.15.0
npm: 8.5.5
Yarn: 1.22.17
pnpm: 6.16.0
Relevant packages:
next: 12.2.3-canary.10
eslint-config-next: 12.2.0
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
Chrome 103.0.5060.114
How are you deploying your application? (if relevant)
Vercel
Describe the Bug
I am using the experimental-edge runtime for an api route. /api/stream. I am creating a custom ReadableStream within this API handler, and returning the ReadableStream to the Response body. This works great locally. However, once I deploy to Vercel, the response resolves with no body. The documentation mentions supporting streaming, so not quite sure what I'm doing wrong.
Not sure if this bug resides on the Next.js side or Vercel.
Below is the simplest repro I can make.
export const config = {
runtime: "experimental-edge",
api: {
bodyParser: false,
responseLimit: false,
},
};
export default async function handler(req: NextRequest, res: NextResponse) {
let count = 0;
const resultStream = new ReadableStream(
{
pull(controller) {
if (count < 10) {
controller.enqueue(JSON.stringify({ foo: "bar" }) + "\n");
count++;
} else {
controller.close();
}
},
},
{
highWaterMark: 1,
size(chunk) {
return 1;
},
}
);
return new Response(resultStream, {
status: 200,
headers: {
"content-type": "text/plain",
"Cache-Control": "no-cache",
},
});
}
Expected Behavior
I expect the stream to be returned in chunks, similar to local dev. {"foo": "bar"}\n should be returned 10 times.
Link to reproduction
https://github.com/jamespantalones/next-js-stream-bug
To Reproduce
npm installnpm run dev- Visit
http://localhost:3000/api/streamand you should see the following:
- Visit same app on Vercel
https://next-js-stream-bug.vercel.app/api/hello - You should see nothing returned.
What is your build command: next build && next export or only next build?
@balazsorban44 does #38862 address this?
@Onyelaudochukwuka do you mind deleting all your comments? i think you are referring to a separate issue entirely. this is only regarding ReadableStreams running on experimental-edge api routes
@crazy-slot just next build
The problem on this example is that you're a enqueuing strings into your ReadableStream while it should only accept Uint8Array. In Next.js it worked because you are responding with a stream from the Edge Runtime and then it is the Next.js Server (in Node.js) the one that processes the stream wiring it into the Node Response which actually allows string. When deployed on Vercel it was failing because strings can't be enqueued to the Response stream but you wouldn't see an error because of a bug catching and logging unhandled rejection.
We have already fixed the issue in both Next.js to be consistent making it fail when enqueuing strings and in Vercel to make sure logs with the error are correctly delivered. If you run the example in the latest Next.js canary you will see an error stating: "TypeError: This ReadableStream did not return bytes.". When you deploy to Vercel you will see the same error TypeError: This ReadableStream did not return bytes..
To fix the code you must first encode the text using new TextEncoder.encode().
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.