brillout / react-streaming

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

SSR of styles from emotion css-in-js library #16

Closed pyrossh closed 1 year ago

pyrossh commented 1 year ago

I'm trying to render the initial styles on the server to avoid CLS. Is there a way to do it currently?

ex: https://emotion.sh/docs/ssr#renderstylestostring

This is what I'm trying but it obviously doesn't work,

import React from 'react'
import { MantineProvider } from '@mantine/core';
import { escapeInject } from 'vite-plugin-ssr'
import { renderStylesToNodeStream } from '@emotion/server'
import { renderToStream } from 'react-streaming/server'
import { PageLayout } from './PageLayout'

export async function render(pageContext) {
  const { Page, pageProps } = pageContext;
  const page = (
    <MantineProvider withGlobalStyles withNormalizeCSS>
      <PageLayout pathname={pageContext.urlPathname}>
        <Page {...pageProps} />
      </PageLayout>
    </MantineProvider>
  )
  const stream = await renderToStream(page, { disable: false })
  const newStream = stream.pipe(renderStylesToNodeStream())
  return escapeInject`<!DOCTYPE html>
    <html lang="en">
      <body>
        <div id="page-view">${newStream}</div>
      </body>
    </html>`
}
pyrossh commented 1 year ago

Here is the example, I'm trying to switch to mantine ui from blueprintjs react-streaming-tigris

brillout commented 1 year ago

Does Emotion support React 18 streaming? I'm not all to familiar with Emotion, but I believe CSS may be generated during the stream, so Emotion needs to be able to emit CSS live during the stream. Does it have an API for that?

react-streaming-tigris

Neat, that looks really nice.

pyrossh commented 1 year ago

Does Emotion support React 18 streaming?

Yes it does have a streaming API,

import { renderToNodeStream } from 'react-dom/server'
import { renderStylesToNodeStream } from '@emotion/server'
import App from './App'

const stream = renderToNodeStream(<App />).pipe(renderStylesToNodeStream())

Now the question is, If renderToStream similar to renderToNodeStream? Which seems like it isn't to me as the styles are not extracted. Or how can I make it compatible with renderToNodeStream.

brillout commented 1 year ago

I see.

FYI React has been doing some work about this: https://github.com/facebook/react/pull/24886.

Context: https://github.com/reactjs/rfcs/pull/219#issuecomment-1115398084.

So I'm not sure what React's recommendation is about this nowadays? I think we should open a ticket over at Emotion see what they think/know about this.

brillout commented 1 year ago

Closing but let me know if you believe there is something that react-streaming can do to help.