Closed devknoll closed 2 years ago
@devknoll it would be great to have some info on how to access the context when the Documents are Server Components. If this is not the proper place for feedback feel free to delete the comment! Thks in advance
Closing as obsolete
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.
Overview
Document
today:getInitialProps
(w/renderPage
) for 3rd party CSS-in-JS support, possibly data fetchingDocument
's new design, in order to support Suspense + Streaming + more:useFlushEffect
hookDetails
Since
Document
only runs on the server, it's naturally a Server Component. However, Server Components are not finalized yet, and won't be until after React 18 is released. However, there's a chicken and egg problem, as we'd like to support incremental progress towards Server Components (and certainly support for Suspense + Streaming) today.The solution is the Next.js Document Server Component, a subset of actual Server Components with additional restrictions. For example, no built-in React hooks (like
useState
) or Suspense are currently supported. This model will be supported until we can officially replacepages/_document.js
withpages/_document.server.js
.The simplest Next.js Document Server Component looks like this:
Conceptually, this is a Server Component that returns a mixed tree of Server/Client Components. There is only one hook supported,
useFlushEffect
, described below.Wrapping the Application
Prior to React 18, many CSS-in-JS libraries would use some global variable that they could write data into during rendering, relying on the fact that rendering would complete synchronously to avoid conflicts. With Suspense in React 18, this is no longer possible: one request could be suspended waiting on I/O, allowing another request to start or unsuspend and access that global data.
Instead, the recommendation is that such libraries use React Context to scope data per request. In order to then allow such libraries to be integrated with Next.js, we add support for a render prop to the
<Main />
component:The render prop will be used to generate the tree that makes up the application content during SSR.
Flushing Styles
Prior to React 18, many CSS-in-JS libraries would just return a script tag for you to insert into your
Document
at the end of the render. With Suspense, content is generated and flushed incrementally, so this pattern of waiting is no longer possible.Instead, the recommendation is that libraries incrementally flush styles to the stream. To streamline this (and expose the stream to 3rd party libraries), Next.js should expose a
useFlushEffect
hook:As per the recommendation, functions passed to the
useFlushEffect
hook will be called right before writing content generated by React.Migration Path
pages/_document
pages/_document
getInitialProps
getInitialProps
Note: all existing class component
Document
s will continue working, but will not support features like streaming or suspense.