Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for functional Document components #28515

Merged
merged 3 commits into from
Aug 26, 2021

Conversation

devknoll
Copy link
Contributor

Adds support for Server Component style pages/_document components, since this component only runs on the server.

Server Components aren't stable yet, we just support a very minimal subset. You may only return HTML elements and elements from next/document. Hooks, suspense, context, etc are not currently supported. It's highly likely that anything more sophisticated than the following example will be broken by a future version of Next.js:

import {
  Html,
  Head,
  Main,
  NextScript
} from 'next/document'

// pages/_document
export default function Document(props) {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Replaces #27794 which has gotten noisy.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk
Copy link
Member

ijjk commented Aug 26, 2021

Stats from current PR

Default Build (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
buildDuration 13s 13.2s ⚠️ +213ms
buildDurationCached 3s 3s -61ms
nodeModulesSize 61.7 MB 61.7 MB ⚠️ +122 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
/ failed reqs 0 0
/ total time (seconds) 2.358 2.348 -0.01
/ avg req/sec 1060.06 1064.85 +4.79
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.303 1.314 ⚠️ +0.01
/error-in-render avg req/sec 1918.47 1902.79 ⚠️ -15.68
Client Bundles (main, webpack, commons)
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
745.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42.2 kB 42.2 kB
main-HASH.js gzip 23.3 kB 23.3 kB
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 67.2 kB 67.2 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
polyfills-a4..dd70.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
_app-HASH.js gzip 979 B 979 B
_error-HASH.js gzip 194 B 194 B
amp-HASH.js gzip 312 B 312 B
css-HASH.js gzip 329 B 329 B
dynamic-HASH.js gzip 2.67 kB 2.67 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 918 B 918 B
image-HASH.js gzip 4.14 kB 4.14 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 1.66 kB 1.66 kB
routerDirect..HASH.js gzip 318 B 318 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 320 B 320 B
bb14e60e810b..30f.css gzip 125 B 125 B
Overall change 13 kB 13 kB
Client Build Manifests
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
_buildManifest.js gzip 491 B 491 B
Overall change 491 B 491 B
Rendered Page Sizes
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
index.html gzip 541 B 541 B
link.html gzip 552 B 552 B
withRouter.html gzip 534 B 534 B
Overall change 1.63 kB 1.63 kB

Webpack 4 Mode (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
buildDuration 10.8s 10.9s ⚠️ +90ms
buildDurationCached 4.7s 4.6s -49ms
nodeModulesSize 61.7 MB 61.7 MB ⚠️ +122 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
/ failed reqs 0 0
/ total time (seconds) 2.389 2.373 -0.02
/ avg req/sec 1046.33 1053.3 +6.97
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.319 1.328 ⚠️ +0.01
/error-in-render avg req/sec 1894.83 1882.95 ⚠️ -11.88
Client Bundles (main, webpack, commons)
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
16.HASH.js gzip 186 B 186 B
677f882d2ed8..HASH.js gzip 14.1 kB 14.1 kB
framework.HASH.js gzip 41.9 kB 41.9 kB
main-HASH.js gzip 10.7 kB 10.7 kB
webpack-HASH.js gzip 1.19 kB 1.19 kB
Overall change 68.1 kB 68.1 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
polyfills-a4..dd70.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
_app-HASH.js gzip 964 B 964 B
_error-HASH.js gzip 3.8 kB 3.8 kB
amp-HASH.js gzip 552 B 552 B
css-HASH.js gzip 333 B 333 B
dynamic-HASH.js gzip 2.87 kB 2.87 kB
head-HASH.js gzip 3.06 kB 3.06 kB
hooks-HASH.js gzip 924 B 924 B
index-HASH.js gzip 231 B 231 B
link-HASH.js gzip 1.64 kB 1.64 kB
routerDirect..HASH.js gzip 298 B 298 B
script-HASH.js gzip 3.03 kB 3.03 kB
withRouter-HASH.js gzip 295 B 295 B
30809af5c834..565.css gzip 125 B 125 B
Overall change 18.1 kB 18.1 kB
Client Build Manifests
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
_buildManifest.js gzip 500 B 500 B
Overall change 500 B 500 B
Rendered Page Sizes
vercel/next.js canary azukaru/next.js x-modern-legacy-doc-2 Change
index.html gzip 584 B 584 B
link.html gzip 597 B 597 B
withRouter.html gzip 578 B 578 B
Overall change 1.76 kB 1.76 kB
Commit: bb29b3c

Copy link
Member

@shuding shuding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code is much cleaner after this refactoring!

This was referenced Sep 3, 2021
kodiakhq bot pushed a commit that referenced this pull request Nov 7, 2021
Adds support for render props to the `<Main>` component, when using the [functional custom `Document`](#28515) style. This allows you to write something like this:

```tsx
export default function Document() {
  const jsxStyleRegistry = createStyleRegistry()
  return (
    <Html>
      <Head />
      <body>
        <Main>
          {content => (
            <StyledJsxWrapper registry={jsxStyleRegistry}>
              {content}
            </StyledJsxWrapper>
          )}
        </Main>
        <NextScript />
      </body>
    </Html>
  )
}
```

In functional document components, this allows the `<App>` to be wrapped, similar to `enhanceApp` (which is only available via `getInitialProps`, which is not supported by functional document components). The primary use for this is for integrating with 3rd party CSS-in-JS libraries, allowing them to attach an `useFlush` handler to [support React 18](reactwg/react-18#110):

```tsx
import { unstable_useFlush as useFlush } from 'next/document'

export default function StyledJsxWrapper({ children, registry }) {
  useFlush(() => {
    /* ... */
  })
  return (
    <StyleRegistry registry={registry}>
      {children}
    </StyleRegistry>
  )
}
```

Support for `useFlush` will be added in a follow up PR.
@vercel vercel locked as resolved and limited conversation to collaborators Jan 27, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants