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

Fix non-concurrent function _document #31628

Merged
merged 5 commits into from Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 19 additions & 11 deletions packages/next/server/render.tsx
Expand Up @@ -1148,24 +1148,32 @@ export async function renderToHTML(
styles: docProps.styles,
}
} else {
const bodyResult = async () => {
const content = (
let bodyResult
const content =
ctx.err && ErrorDebug ? (
<Body>
{ctx.err && ErrorDebug ? (
<ErrorDebug error={ctx.err} />
) : (
getWrappedApp(
<App {...props} Component={Component} router={router} />
)
<ErrorDebug error={ctx.err} />
</Body>
) : (
<Body>
{getWrappedApp(
<App {...props} Component={Component} router={router} />
)}
</Body>
)

return concurrentFeatures
? process.browser
if (concurrentFeatures) {
bodyResult = async () => {
return process.browser
? await renderToWebStream(content)
: await renderToNodeStream(content, generateStaticHTML)
: piperFromArray([ReactDOMServer.renderToString(content)])
}
} else {
// for non-concurrent rendering we need to ensure App is rendered
// before _document so that updateHead is called/collected before
// rendering _document's head
const result = piperFromArray([ReactDOMServer.renderToString(content)])
bodyResult = () => result
}

return {
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/next-head/app/components/meta.js
@@ -0,0 +1,12 @@
import Head from 'next/head'

export function Meta(props) {
return (
<>
<Head>
<meta name="test-head-3" content="hello" />
<meta name="test-head-4" content="hello" />
</Head>
</>
)
}
13 changes: 13 additions & 0 deletions test/e2e/next-head/app/pages/_document.js
@@ -0,0 +1,13 @@
import { Html, Head, Main, NextScript } from 'next/document'

export default function MyDocument() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
15 changes: 15 additions & 0 deletions test/e2e/next-head/app/pages/index.js
@@ -0,0 +1,15 @@
import Head from 'next/head'
import { Meta } from '../components/meta'

export default function Page(props) {
return (
<>
<Head>
<meta name="test-head-1" content="hello" />
<meta name="test-head-2" content="hello" />
</Head>
<Meta />
<p>index page</p>
</>
)
}
41 changes: 41 additions & 0 deletions test/e2e/next-head/index.test.ts
@@ -0,0 +1,41 @@
import { createNext, FileRef } from 'e2e-utils'
import { renderViaHTTP } from 'next-test-utils'
import cheerio from 'cheerio'
import webdriver from 'next-webdriver'
import { NextInstance } from 'test/lib/next-modes/base'
import { join } from 'path'

describe('should set-up next', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
pages: new FileRef(join(__dirname, 'app/pages')),
components: new FileRef(join(__dirname, 'app/components')),
},
})
})
afterAll(() => next.destroy())

it('should have correct head tags in initial document', async () => {
const html = await renderViaHTTP(next.url, '/')
const $ = cheerio.load(html)

for (let i = 1; i < 5; i++) {
expect($(`meta[name="test-head-${i}"]`).attr()['content']).toBe('hello')
}
})

it('should have correct head tags after hydration', async () => {
const browser = await webdriver(next.url, '/')

for (let i = 1; i < 5; i++) {
expect(
await browser
.elementByCss(`meta[name="test-head-${i}"]`)
.getAttribute('content')
).toBe('hello')
}
})
})