brillout / react-streaming

React Streaming. Full-fledged & Easy.
MIT License
216 stars 14 forks source link

Incorrectly injects in between HTML on Cloudflare Workers #45

Open shahyar opened 1 week ago

shahyar commented 1 week ago

I have been trying to figure this out for a while, but for some reason, sometimes react-streaming/vike-react is outputting the initData blocks in the middle of my HTML.

For example (abbreviated for easier reading):

<span aria-hidden="true"
class="pointer-events-none box-border a<script class="react-streaming_initData" type="application/json">{"key":"[\"!undefined\",\"!undefined\",\"/api/...\",\"!undefined\",{\"data\":...]","value":"get:/api/...","elementId":":R1lki:"}</script>nimate-pulse cursor-default ...">

It doesn't happen on Vite's dev server. The problem seems to be worse the longer a page takes to render/the bigger the data in the async hydration.

The worker is pretty standard:

    const pageContext = await renderPage<PageContext, PageContext>(pageContextInit as PageContext);
    // ...
    const { statusCode, headers: resHeaders } = pageContext.httpResponse;
    const stream = httpResponse.getReadableWebStream();

    const response = new Response(stream, {
      headers: resHeaders,
      status: statusCode,
    });

    return response;

I also tried swapping it out for a TransformStream with httpResponse.pipe, but that had the same results.

I don't have an example repo yet, as this is affecting a much larger codebase with some pretty complex workflows. But this is an example of the code which caused this:

  const baseCacheKey = useAsync(
    [req.id, req.name, req.input, deepOpts?.cache, deepQuery],
    async () => {
      const requestSchema = {
        // ...
      };
      const requestOpts = {
        // ...
      };

      // this function runs xxhash-wasm and returns a hash
      return await requestCacheKey(requestSchema, requestOpts);
    },
  );

This page's config is:

{ streamIsRequired: true, stream: true, ssr: true }

I believe setting stream: false will fix it, but that also gets rid of the React Stream.

Am I doing something wrong? Is Cloudflare doing something wrong? Or is this just a very weird edge case?

brillout commented 1 week ago

Are you using the latest react-streaming version? Make sure to double check you're using the latest version as recent versions fixed issues with that.

shahyar commented 1 week ago

Definitely on the latest version.

brillout commented 6 days ago

Run DEBUG=react-streaming:chunks npm run ... and paste the debug logs you get here.

brillout commented 6 days ago

Or provide a minimal reproduction if you prefer.