diff --git a/errors/manifest.json b/errors/manifest.json index d0260def43712..9c52478cbf19d 100644 --- a/errors/manifest.json +++ b/errors/manifest.json @@ -279,6 +279,10 @@ "title": "no-document-viewport-meta", "path": "/errors/no-document-viewport-meta.md" }, + { + "title": "no-duplicate-head", + "path": "/errors/no-duplicate-head.md" + }, { "title": "no-head-import-in-document", "path": "/errors/no-head-import-in-document.md" diff --git a/errors/no-duplicate-head.md b/errors/no-duplicate-head.md new file mode 100644 index 0000000000000..ed16c4f102b0d --- /dev/null +++ b/errors/no-duplicate-head.md @@ -0,0 +1,38 @@ +# No Duplicate Head + +### Why This Error Occurred + +More than a single instance of the `
+ +` component was used in a single custom document. This can cause unexpected behavior in your application. + +### Possible Ways to Fix It + +Only use a single `
` component in your custom document in `pages/_document.js`. + +```jsx +// pages/_document.js +import Document, { Html, Head, Main, NextScript } from 'next/document' + +class MyDocument extends Document { + static async getInitialProps(ctx) { + //... + } + + render() { + return ( + +
+
. See: https://nextjs.org/docs/messages/no-duplicate-head', + }) + } + } + } + }, + } + }, +} diff --git a/test/eslint-plugin-next/no-duplicate-head.test.js b/test/eslint-plugin-next/no-duplicate-head.test.js new file mode 100644 index 0000000000000..579865966cba8 --- /dev/null +++ b/test/eslint-plugin-next/no-duplicate-head.test.js @@ -0,0 +1,142 @@ +const rule = require('@next/eslint-plugin-next/lib/rules/no-duplicate-head') + +const RuleTester = require('eslint').RuleTester + +RuleTester.setDefaultConfig({ + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + ecmaFeatures: { + modules: true, + jsx: true, + }, + }, +}) + +var ruleTester = new RuleTester() +ruleTester.run('no-duplicate-head', rule, { + valid: [ + { + code: `import Document, { Html, Head, Main, NextScript } from 'next/document' + + class MyDocument extends Document { + static async getInitialProps(ctx) { + //... + } + + render() { + return ( + +
+ + ) + } + } + + export default MyDocument + `, + filename: 'pages/_document.js', + }, + { + code: `import Document, { Html, Head, Main, NextScript } from 'next/document' + + class MyDocument extends Document { + render() { + return ( + +
+ + + + + ) + } + } + + export default MyDocument + `, + filename: 'pages/_document.tsx', + }, + ], + invalid: [ + { + code: ` + import Document, { Html, Main, NextScript } from 'next/document' + import Head from 'next/head' + + class MyDocument extends Document { + render() { + return ( + +
+
+
+ + ) + } + } + + export default MyDocument + `, + filename: 'pages/_document.js', + errors: [ + { + message: + 'Do not include multiple instances of
. See: https://nextjs.org/docs/messages/no-duplicate-head', + type: 'JSXElement', + }, + { + message: + 'Do not include multiple instances of
. See: https://nextjs.org/docs/messages/no-duplicate-head', + type: 'JSXElement', + }, + ], + }, + { + code: ` + import Document, { Html, Main, NextScript } from 'next/document' + import Head from 'next/head' + + class MyDocument extends Document { + render() { + return ( + +
+ + + +