forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add error when document component isn't rendered (vercel#16459)
If a custom `_document` is added but not all of the expected document components are rendered it can cause unintended errors as noticed in vercel#10219 so this adds detecting when one of the expected document components isn't rendered and shows an error. Closes: vercel#10219
- Loading branch information
Showing
6 changed files
with
228 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Missing Document Components | ||
|
||
#### Why This Error Occurred | ||
|
||
In your custom `pages/_document` an expected sub-component was not rendered. | ||
|
||
#### Possible Ways to Fix It | ||
|
||
Make sure to import and render all of the expected `Document` components. | ||
|
||
### Useful Links | ||
|
||
- [Custom Document Docs](https://nextjs.org/docs/advanced-features/custom-document) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
test/integration/missing-document-component-error/pages/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function Index() { | ||
return <p>Index page</p> | ||
} |
159 changes: 159 additions & 0 deletions
159
test/integration/missing-document-component-error/test/index.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* eslint-env jest */ | ||
|
||
import fs from 'fs-extra' | ||
import { join } from 'path' | ||
import { | ||
findPort, | ||
killApp, | ||
launchApp, | ||
check, | ||
renderViaHTTP, | ||
} from 'next-test-utils' | ||
|
||
jest.setTimeout(1000 * 60 * 2) | ||
|
||
const appDir = join(__dirname, '..') | ||
const docPath = join(appDir, 'pages/_document.js') | ||
let appPort | ||
let app | ||
|
||
const checkMissing = async (missing = [], docContent) => { | ||
await fs.writeFile(docPath, docContent) | ||
let stderr = '' | ||
|
||
appPort = await findPort() | ||
app = await launchApp(appDir, appPort, { | ||
onStderr(msg) { | ||
stderr += msg || '' | ||
}, | ||
}) | ||
|
||
await renderViaHTTP(appPort, '/') | ||
|
||
await check(() => stderr, new RegExp(`missing-document-component`)) | ||
await check(() => stderr, new RegExp(`${missing.join(', ')}`)) | ||
|
||
await killApp(app) | ||
await fs.remove(docPath) | ||
} | ||
|
||
describe('Missing _document components error', () => { | ||
it('should detect missing Html component', async () => { | ||
await checkMissing( | ||
['Html'], | ||
` | ||
import Document, { Head, Main, NextScript } from 'next/document' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<html> | ||
<Head /> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
` | ||
) | ||
}) | ||
|
||
it('should detect missing Head component', async () => { | ||
await checkMissing( | ||
['Head'], | ||
` | ||
import Document, { Html, Main, NextScript } from 'next/document' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
` | ||
) | ||
}) | ||
|
||
it('should detect missing Main component', async () => { | ||
await checkMissing( | ||
['Main'], | ||
` | ||
import Document, { Html, Head, NextScript } from 'next/document' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<Head /> | ||
<body> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
` | ||
) | ||
}) | ||
|
||
it('should detect missing NextScript component', async () => { | ||
await checkMissing( | ||
['NextScript'], | ||
` | ||
import Document, { Html, Head, Main } from 'next/document' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<body> | ||
<Main /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
` | ||
) | ||
}) | ||
|
||
it('should detect multiple missing document components', async () => { | ||
await checkMissing( | ||
['Head', 'NextScript'], | ||
` | ||
import Document, { Html, Main } from 'next/document' | ||
class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html> | ||
<body> | ||
<Main /> | ||
</body> | ||
</Html> | ||
) | ||
} | ||
} | ||
export default MyDocument | ||
` | ||
) | ||
}) | ||
}) |