Skip to content

Commit

Permalink
Fix component frameworks on Vercel Edge (#4667)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
bholmesdev and bholmesdev authored Sep 7, 2022
1 parent 4b73d34 commit 9290b24
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
6 changes: 6 additions & 0 deletions .changeset/tasty-owls-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/react': patch
---

Fix framework components on Vercel Edge
5 changes: 4 additions & 1 deletion packages/astro/src/runtime/server/render/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export async function renderPage(
controller.enqueue(encoder.encode('<!DOCTYPE html>\n'));
}
}
controller.enqueue(encoder.encode(html));
// Convert HTML object to string
// for environments that won't "toString" automatically
// (ex. Cloudflare and Vercel Edge)
controller.enqueue(encoder.encode(String(html)));
i++;
}
controller.close();
Expand Down
27 changes: 20 additions & 7 deletions packages/integrations/react/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,27 @@ async function renderToStaticNodeStreamAsync(vnode) {
});
}

/**
* Use a while loop instead of "for await" due to cloudflare and Vercel Edge issues
* See https://github.com/facebook/react/issues/24169
*/
async function readResult(stream) {
const reader = stream.getReader();
let result = '';
const decoder = new TextDecoder('utf-8')
while (true) {
const { done, value } = await reader.read();
if (done) {
return result;
}
result += decoder.decode(value, { stream: true });
}
}

async function renderToReadableStreamAsync(vnode) {
const decoder = new TextDecoder();
const stream = await ReactDOM.renderToReadableStream(vnode);
let html = '';
for await (const chunk of stream) {
html += decoder.decode(chunk);
}
return html;
return await readResult(
await ReactDOM.renderToReadableStream(vnode),
);
}

export default {
Expand Down

0 comments on commit 9290b24

Please sign in to comment.