Skip to content

Commit 9290b24

Browse files
authored
Fix component frameworks on Vercel Edge (#4667)
* fix: use while instead of "for await" in react integration * fix: cast HTML to string to fix other integrations * docs: add comment on encode(String(html)) * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev>
1 parent 4b73d34 commit 9290b24

3 files changed

Lines changed: 30 additions & 8 deletions

File tree

.changeset/tasty-owls-watch.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'astro': patch
3+
'@astrojs/react': patch
4+
---
5+
6+
Fix framework components on Vercel Edge

packages/astro/src/runtime/server/render/page.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ export async function renderPage(
7979
controller.enqueue(encoder.encode('<!DOCTYPE html>\n'));
8080
}
8181
}
82-
controller.enqueue(encoder.encode(html));
82+
// Convert HTML object to string
83+
// for environments that won't "toString" automatically
84+
// (ex. Cloudflare and Vercel Edge)
85+
controller.enqueue(encoder.encode(String(html)));
8386
i++;
8487
}
8588
controller.close();

packages/integrations/react/server.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,27 @@ async function renderToStaticNodeStreamAsync(vnode) {
135135
});
136136
}
137137

138+
/**
139+
* Use a while loop instead of "for await" due to cloudflare and Vercel Edge issues
140+
* See https://github.com/facebook/react/issues/24169
141+
*/
142+
async function readResult(stream) {
143+
const reader = stream.getReader();
144+
let result = '';
145+
const decoder = new TextDecoder('utf-8')
146+
while (true) {
147+
const { done, value } = await reader.read();
148+
if (done) {
149+
return result;
150+
}
151+
result += decoder.decode(value, { stream: true });
152+
}
153+
}
154+
138155
async function renderToReadableStreamAsync(vnode) {
139-
const decoder = new TextDecoder();
140-
const stream = await ReactDOM.renderToReadableStream(vnode);
141-
let html = '';
142-
for await (const chunk of stream) {
143-
html += decoder.decode(chunk);
144-
}
145-
return html;
156+
return await readResult(
157+
await ReactDOM.renderToReadableStream(vnode),
158+
);
146159
}
147160

148161
export default {

0 commit comments

Comments
 (0)