From 5211ac5caee1f6764cb08a3070974c02820c5062 Mon Sep 17 00:00:00 2001
From: Michael Novotny
Date: Mon, 13 Jun 2022 21:17:42 -0500
Subject: [PATCH] Adds consistency to ESLint rules. (#34335)
* Adds consistency to ESLint rules.
* Fixes lint errors.
* Fixes manifest.
* Adds missing title.
* Fixes copy / paste error.
Co-authored-by: Lee Robinson
* Update errors/no-script-in-document.md
Co-authored-by: Lee Robinson
* Update errors/no-sync-scripts.md
Co-authored-by: Lee Robinson
* Updates a couple of rule descriptions.
* Adds redirects.
* Fixes unit tests.
* Removes duplicated section.
* Updates `no-before-interactive-script-outside-document` description.
* Fixes lint.
* Fixes integration tests.
* Adds description to `no-before-interactive-script-outside-document` documentation.
* Removes `link-passhref` from rules list.
* Updates remaining `pages/_middleware.js` references.
* Adds consistancy to messaging in new `no-styled-jsx-in-document` rule.
* Apply suggestions from code review
* Apply suggestions from code review
Co-authored-by: Lee Robinson
Co-authored-by: Tim Neutkens
Co-authored-by: JJ Kasper
---
docs/basic-features/eslint.md | 43 ++++++-----
errors/google-font-display.md | 7 +-
errors/google-font-preconnect.md | 2 +
errors/inline-script-id.md | 4 +-
errors/link-passhref.md | 4 +-
errors/manifest.json | 26 ++++++-
errors/next-script-for-ga.md | 2 +
...ore-interactive-script-outside-document.md | 10 ++-
errors/no-css-tags.md | 4 +-
errors/no-document-import-in-page.md | 2 +
errors/no-duplicate-head.md | 2 +
errors/no-head-element.md | 4 +-
errors/no-head-import-in-document.md | 2 +
errors/no-html-link-for-pages.md | 4 +-
errors/no-img-element.md | 4 +-
errors/no-page-custom-font.md | 4 +-
...nent.md => no-script-component-in-head.md} | 8 +-
errors/no-script-in-document-page.md | 29 -------
errors/no-script-in-document.md | 31 ++++++++
errors/no-server-import-in-page.md | 2 +
errors/no-styled-jsx-in-document.md | 2 +
errors/no-sync-scripts.md | 15 +++-
errors/no-title-in-document-head.md | 4 +-
errors/no-unwanted-polyfillio.md | 8 +-
packages/eslint-plugin-next/lib/index.js | 72 +++++++++---------
.../lib/rules/google-font-display.js | 18 +++--
.../lib/rules/google-font-preconnect.js | 8 +-
.../lib/rules/inline-script-id.js | 9 ++-
.../lib/rules/next-script-for-ga.js | 14 ++--
...ore-interactive-script-outside-document.js | 10 ++-
.../lib/rules/no-css-tags.js | 75 +++++++++++--------
.../lib/rules/no-document-import-in-page.js | 8 +-
.../lib/rules/no-duplicate-head.js | 10 ++-
.../lib/rules/no-head-element.js | 9 ++-
.../lib/rules/no-head-import-in-document.js | 8 +-
.../lib/rules/no-html-link-for-pages.js | 17 +++--
.../lib/rules/no-img-element.js | 8 +-
.../lib/rules/no-page-custom-font.js | 14 ++--
.../lib/rules/no-script-component-in-head.js | 10 ++-
.../lib/rules/no-server-import-in-page.js | 7 +-
.../lib/rules/no-styled-jsx-in-document.js | 8 +-
.../lib/rules/no-sync-scripts.js | 61 ++++++++-------
.../lib/rules/no-title-in-document-head.js | 10 ++-
.../eslint-plugin-next/lib/rules/no-typos.js | 2 +-
.../lib/rules/no-unwanted-polyfillio.js | 11 +--
test/integration/eslint/test/index.test.js | 48 ++++++------
.../google-font-display.test.ts | 10 +--
.../google-font-preconnect.test.ts | 4 +-
.../inline-script-id.test.ts | 2 +-
.../next-script-for-ga.test.ts | 2 +-
...nteractive-script-outside-document.test.ts | 2 +-
.../no-document-import-in-page.test.ts | 6 +-
.../no-duplicate-head.test.ts | 22 +++---
.../no-head-element.test.ts | 4 +-
.../no-head-import-in-document.test.ts | 30 ++++----
.../no-html-link-for-pages.test.ts | 8 +-
.../eslint-plugin-next/no-img-element.test.ts | 4 +-
.../no-page-custom-font.test.ts | 6 +-
.../no-script-component-in-head.test.ts | 4 +-
.../no-server-import-in-page.test.ts | 2 +-
.../no-styled-jsx-in-document.test.ts | 9 +--
.../no-sync-scripts.test.ts | 4 +-
.../no-title-in-document-head.test.ts | 4 +-
63 files changed, 445 insertions(+), 338 deletions(-)
rename errors/{no-script-component-in-head-component.md => no-script-component-in-head.md} (75%)
delete mode 100644 errors/no-script-in-document-page.md
create mode 100644 errors/no-script-in-document.md
diff --git a/docs/basic-features/eslint.md b/docs/basic-features/eslint.md
index b85d16f44cacb..0d97a658b891b 100644
--- a/docs/basic-features/eslint.md
+++ b/docs/basic-features/eslint.md
@@ -80,28 +80,31 @@ This will take precedence over the configuration from `next.config.js`.
Next.js provides an ESLint plugin, [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-next), already bundled within the base configuration that makes it possible to catch common issues and problems in a Next.js application. The full set of rules is as follows:
-| | Rule | Description |
-| :-: | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
-| ✔️ | [next/google-font-display](/docs/messages/google-font-display.md) | Enforce optional or swap font-display behavior with Google Fonts |
-| ✔️ | [next/google-font-preconnect](/docs/messages/google-font-preconnect.md) | Enforce preconnect usage with Google Fonts |
-| ✔️ | [next/link-passhref](/docs/messages/link-passhref.md) | Enforce passHref prop usage with custom Link components |
-| ✔️ | [next/no-css-tags](/docs/messages/no-css-tags.md) | Prevent manual stylesheet tags |
-| ✔️ | [next/no-document-import-in-page](/docs/messages/no-document-import-in-page.md) | Disallow importing next/document outside of pages/document.js |
-| ✔️ | [next/no-head-import-in-document](/docs/messages/no-head-import-in-document.md) | Disallow importing next/head in pages/document.js |
-| ✔️ | [next/no-html-link-for-pages](/docs/messages/no-html-link-for-pages.md) | Prohibit HTML anchor links to pages without a Link component |
-| ✔️ | [next/no-img-element](/docs/messages/no-img-element.md) | Prohibit usage of HTML <img> element |
-| ✔️ | [next/no-head-element](/docs/messages/no-head-element.md) | Prohibit usage of HTML <head> element |
-| ✔️ | [next/no-page-custom-font](/docs/messages/no-page-custom-font.md) | Prevent page-only custom fonts |
-| ✔️ | [next/no-sync-scripts](/docs/messages/no-sync-scripts.md) | Forbid synchronous scripts |
-| ✔️ | [next/no-title-in-document-head](/docs/messages/no-title-in-document-head.md) | Disallow using <title> with Head from next/document |
-| ✔️ | [next/no-unwanted-polyfillio](/docs/messages/no-unwanted-polyfillio.md) | Prevent duplicate polyfills from Polyfill.io |
-| ✔️ | [next/inline-script-id](/docs/messages/inline-script-id.md) | Enforce id attribute on next/script components with inline content |
-| ✔️ | next/no-typos | Ensure no typos were made declaring [Next.js's data fetching function](/docs/basic-features/data-fetching/overview.md) |
-| ✔️ | [next/next-script-for-ga](/docs/messages/next-script-for-ga.md) | Use the Script component to defer loading of the script until necessary. |
-| ✔️ | [next/no-styled-jsx-in-document](/docs/messages/no-styled-jsx-in-document.md) | styled-jsx should not be used in \_document |
-
- ✔: Enabled in the recommended configuration
+| | Rule | Description |
+| :-: | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
+| ✔️ | [@next/next/google-font-display](/docs/messages/google-font-display.md) | Enforce font-display behavior with Google Fonts. |
+| ✔️ | [@next/next/google-font-preconnect](/docs/messages/google-font-preconnect.md) | Ensure `preconnect` is used with Google Fonts. |
+| ✔️ | [@next/next/inline-script-id](/docs/messages/inline-script-id.md) | Enforce `id` attribute on `next/script` components with inline content. |
+| ✔️ | [@next/next/next-script-for-ga](/docs/messages/next-script-for-ga.md) | Prefer `next/script` component when using the inline script for Google Analytics. |
+| ✔️ | [@next/next/no-before-interactive-script-outside-document](/docs/messages/no-before-interactive-script-outside-document.md) | Prevent usage of `next/script`'s `beforeInteractive` strategy outside of `pages/_document.js`. |
+| ✔️ | [@next/next/no-css-tags](/docs/messages/no-css-tags.md) | Prevent manual stylesheet tags. |
+| ✔️ | [@next/next/no-document-import-in-page](/docs/messages/no-document-import-in-page.md) | Prevent importing `next/document` outside of `pages/_document.js`. |
+| ✔️ | [@next/next/no-duplicate-head](/docs/messages/no-duplicate-head.md) | Prevent duplicate usage of `` in `pages/_document.js`. |
+| ✔️ | [@next/next/no-head-element](/docs/messages/no-head-element.md) | Prevent usage of `` element. |
+| ✔️ | [@next/next/no-head-import-in-document](/docs/messages/no-head-import-in-document.md) | Prevent usage of `next/head` in `pages/_document.js`. |
+| ✔️ | [@next/next/no-html-link-for-pages](/docs/messages/no-html-link-for-pages.md) | Prevent usage of `` elements to navigate to internal Next.js pages. |
+| ✔️ | [@next/next/no-img-element](/docs/messages/no-img-element.md) | Prevent usage of `` element to prevent layout shift. |
+| ✔️ | [@next/next/no-page-custom-font](/docs/messages/no-page-custom-font.md) | Prevent page-only custom fonts. |
+| ✔️ | [@next/next/no-script-component-in-head](/docs/messages/no-script-component-in-head.md) | Prevent usage of `next/script` in `next/head` component. |
+| ✔️ | [@next/next/no-server-import-in-page](/docs/messages/no-server-import-in-page.md) | Prevent usage of `next/server` outside of `middleware.js`. |
+| ✔️ | [@next/next/no-styled-jsx-in-document](/docs/messages/no-styled-jsx-in-document.md) | Prevent usage of `styled-jsx` in `pages/_document.js`. |
+| ✔️ | [@next/next/no-sync-scripts](/docs/messages/no-sync-scripts.md) | Prevent synchronous scripts. |
+| ✔️ | [@next/next/no-title-in-document-head](/docs/messages/no-title-in-document-head.md) | Prevent usage of `` with `Head` component from `next/document`. |
+| ✔️ | @next/next/no-typos | Prevent common typos in [Next.js's data fetching functions](/docs/basic-features/data-fetching.md) |
+| ✔️ | [@next/next/no-unwanted-polyfillio](/docs/messages/no-unwanted-polyfillio.md) | Prevent duplicate polyfills from Polyfill.io. |
+
If you already have ESLint configured in your application, we recommend extending from this plugin directly instead of including `eslint-config-next` unless a few conditions are met. Refer to the [Recommended Plugin Ruleset](/docs/basic-features/eslint.md#recommended-plugin-ruleset) to learn more.
### Custom Settings
diff --git a/errors/google-font-display.md b/errors/google-font-display.md
index 39d7b597389c5..bd01159cba2e5 100644
--- a/errors/google-font-display.md
+++ b/errors/google-font-display.md
@@ -1,8 +1,10 @@
# Google Font Display
+> Enforce font-display behavior with Google Fonts.
+
### Why This Error Occurred
-For a Google Font, the `display` descriptor was either not assigned or set to `auto`, `fallback`, or `block`.
+For a Google Font, the font-display descriptor was either missing or set to `auto`, `block`, or `fallback`, which are not recommended.
### Possible Ways to Fix It
@@ -29,9 +31,10 @@ Specifying `display=optional` minimizes the risk of invisible text or layout shi
### When Not To Use It
-If you want to specifically display a font using a `block` or `fallback` strategy, then you can disable this rule.
+If you want to specifically display a font using an `auto`, `block`, or `fallback` strategy, then you can disable this rule.
### Useful Links
+- [Controlling Font Performance with font-display](https://developer.chrome.com/blog/font-display/)
- [Google Fonts API Docs](https://developers.google.com/fonts/docs/css2#use_font-display)
- [CSS `font-display` property](https://www.w3.org/TR/css-fonts-4/#font-display-desc)
diff --git a/errors/google-font-preconnect.md b/errors/google-font-preconnect.md
index d95d72dba9bdb..1731f22322f0b 100644
--- a/errors/google-font-preconnect.md
+++ b/errors/google-font-preconnect.md
@@ -1,5 +1,7 @@
# Google Font Preconnect
+> Ensure `preconnect` is used with Google Fonts.
+
### Why This Error Occurred
A preconnect resource hint was not used with a request to the Google Fonts domain. Adding `preconnect` is recommended to initiate an early connection to the origin.
diff --git a/errors/inline-script-id.md b/errors/inline-script-id.md
index fe7f1250be733..a6cbd6301f863 100644
--- a/errors/inline-script-id.md
+++ b/errors/inline-script-id.md
@@ -1,4 +1,6 @@
-# next/script components with inline content require an `id` attribute
+# Inline script id
+
+> Enforce `id` attribute on `next/script` components with inline content.
## Why This Error Occurred
diff --git a/errors/link-passhref.md b/errors/link-passhref.md
index 33fec658066e0..e22a15b718697 100644
--- a/errors/link-passhref.md
+++ b/errors/link-passhref.md
@@ -1,4 +1,6 @@
-# Link passHref
+# Link `passHref`
+
+> Ensure `passHref` is used with custom `Link` components.
### Why This Error Occurred
diff --git a/errors/manifest.json b/errors/manifest.json
index d74dea075e4b6..4205dc491e8f4 100644
--- a/errors/manifest.json
+++ b/errors/manifest.json
@@ -563,16 +563,34 @@
"path": "/errors/sharp-version-avif.md"
},
{
- "title": "script-in-document-page",
- "path": "/errors/no-script-in-document-page.md"
+ "path": "/errors/no-script-in-document-page.md",
+ "redirect": {
+ "destination": "/errors/no-script-in-document"
+ }
+ },
+ {
+ "title": "no-script-in-document",
+ "path": "/errors/no-script-in-document.md"
},
{
"title": "before-interactive-script-outside-document",
"path": "/errors/no-before-interactive-script-outside-document.md"
},
{
- "title": "script-component-in-head-component",
- "path": "/errors/no-script-component-in-head-component.md"
+ "path": "/errors/no-script-in-head-component.md",
+ "redirect": {
+ "destination": "/errors/no-script-component-in-head"
+ }
+ },
+ {
+ "path": "/errors/no-script-component-in-head-component.md",
+ "redirect": {
+ "destination": "/errors/no-script-component-in-head"
+ }
+ },
+ {
+ "title": "no-script-component-in-head",
+ "path": "/errors/no-script-component-in-head.md"
},
{
"title": "script-tags-in-head-component",
diff --git a/errors/next-script-for-ga.md b/errors/next-script-for-ga.md
index 3df685bebcda9..4dda57e70d1f5 100644
--- a/errors/next-script-for-ga.md
+++ b/errors/next-script-for-ga.md
@@ -1,5 +1,7 @@
# Next Script for Google Analytics
+> Prefer `next/script` component when using the inline script for Google Analytics.
+
### Why This Error Occurred
An inline script was used for Google analytics which might impact your webpage's performance.
diff --git a/errors/no-before-interactive-script-outside-document.md b/errors/no-before-interactive-script-outside-document.md
index 9ba97c59e8053..e40c3f67129c0 100644
--- a/errors/no-before-interactive-script-outside-document.md
+++ b/errors/no-before-interactive-script-outside-document.md
@@ -1,15 +1,17 @@
-# beforeInteractive Script component outside \_document.js
+# No Before Interactive Script Outside Document
+
+> Prevent usage of `next/script`'s `beforeInteractive` strategy outside of `pages/_document.js`.
#### Why This Error Occurred
-You can't use the `next/script` component with the `beforeInteractive` strategy outside the `_document.js` page. That's because `beforeInteractive` strategy only works inside **\_document.js** and is designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).
+You cannot use the `next/script` component with the `beforeInteractive` strategy outside `pages/_document.js`. That's because `beforeInteractive` strategy only works inside **`pages/_document.js`** and is designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).
#### Possible Ways to Fix It
-If you want a global script, move the script inside `_document.js` page.
+If you want a global script, move the script inside `pages/_document.js`.
```jsx
-// In _document.js
+// In `pages/_document.js`
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'
diff --git a/errors/no-css-tags.md b/errors/no-css-tags.md
index 8a3e5540402ca..c9926b25b81f1 100644
--- a/errors/no-css-tags.md
+++ b/errors/no-css-tags.md
@@ -1,8 +1,10 @@
# No CSS Tags
+> Prevent manual stylesheet tags.
+
### Why This Error Occurred
-An HTML link element was used to link to an external stylesheet. This can negatively affect CSS resource loading on your web page.
+A `link` element was used to link to an external stylesheet. This can negatively affect CSS resource loading on your webpage.
### Possible Ways to Fix It
diff --git a/errors/no-document-import-in-page.md b/errors/no-document-import-in-page.md
index 8abbf7ceb3d0b..bb2713856f9a6 100644
--- a/errors/no-document-import-in-page.md
+++ b/errors/no-document-import-in-page.md
@@ -1,5 +1,7 @@
# No Document Import in Page
+> Prevent importing `next/document` outside of `pages/_document.js`.
+
### Why This Error Occurred
`next/document` was imported in a page outside of `pages/_document.js` (or `pages/_document.tsx` if you are using TypeScript). This can cause unexpected issues in your application.
diff --git a/errors/no-duplicate-head.md b/errors/no-duplicate-head.md
index ed16c4f102b0d..4ba4314f18456 100644
--- a/errors/no-duplicate-head.md
+++ b/errors/no-duplicate-head.md
@@ -1,5 +1,7 @@
# No Duplicate Head
+> Prevent duplicate usage of `` in `pages/_document.js`.
+
### 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.
diff --git a/errors/no-head-element.md b/errors/no-head-element.md
index 670894e64a445..f3bd5ca349270 100644
--- a/errors/no-head-element.md
+++ b/errors/no-head-element.md
@@ -1,8 +1,10 @@
# No Head Element
+> Prevent usage of `` element.
+
### Why This Error Occurred
-An HTML `` element was used to include page-level metadata, but this can cause unexpected behavior in a Next.js application. Use Next.js' built-in `` component instead.
+A `` element was used to include page-level metadata, but this can cause unexpected behavior in a Next.js application. Use Next.js' built-in `next/head` component instead.
### Possible Ways to Fix It
diff --git a/errors/no-head-import-in-document.md b/errors/no-head-import-in-document.md
index 9336cff2c8eca..cb9c18e08eb88 100644
--- a/errors/no-head-import-in-document.md
+++ b/errors/no-head-import-in-document.md
@@ -1,5 +1,7 @@
# No Head Import in Document
+> Prevent usage of `next/head` in `pages/_document.js`.
+
### Why This Error Occurred
`next/head` was imported in `pages/_document.js`. This can cause unexpected issues in your application.
diff --git a/errors/no-html-link-for-pages.md b/errors/no-html-link-for-pages.md
index 38457ae4a46ab..32e124dc11fda 100644
--- a/errors/no-html-link-for-pages.md
+++ b/errors/no-html-link-for-pages.md
@@ -1,8 +1,10 @@
# No HTML link for pages
+> Prevent usage of `` elements to navigate to internal Next.js pages.
+
### Why This Error Occurred
-An HTML anchor element, ``, was used to navigate to a page route without using the `Link` component.
+An `` element was used to navigate to a page route without using the `next/link` component, causing unnecessary full page refreshes.
The `Link` component is required in order to enable client-side route transitions between pages and provide a single-page app experience.
diff --git a/errors/no-img-element.md b/errors/no-img-element.md
index 532dac586cb25..db4d31f363f26 100644
--- a/errors/no-img-element.md
+++ b/errors/no-img-element.md
@@ -1,8 +1,10 @@
# No Img Element
+> Prevent usage of `` element to prevent layout shift.
+
### Why This Error Occurred
-An HTML `` element was used to display an image. For better performance and automatic Image Optimization, use Next.js' built-in image component instead.
+An `` element was used to display an image. For better performance and automatic Image Optimization, use `next/image` instead.
### Possible Ways to Fix It
diff --git a/errors/no-page-custom-font.md b/errors/no-page-custom-font.md
index edcea71d99b33..2f2e51e3d28e5 100644
--- a/errors/no-page-custom-font.md
+++ b/errors/no-page-custom-font.md
@@ -1,9 +1,11 @@
# No Page Custom Font
+> Prevent page-only custom fonts.
+
### Why This Error Occurred
- The custom font you're adding was added to a page - this only adds the font to the specific page and not the entire application.
-- The custom font you're adding was added to a separate component within `Document` - this disables automatic font optimization.
+- The custom font you're adding was added to a separate component within `pages/_document.js` - this disables automatic font optimization.
### Possible Ways to Fix It
diff --git a/errors/no-script-component-in-head-component.md b/errors/no-script-component-in-head.md
similarity index 75%
rename from errors/no-script-component-in-head-component.md
rename to errors/no-script-component-in-head.md
index c070deb14ec6b..50503ebe0eaec 100644
--- a/errors/no-script-component-in-head-component.md
+++ b/errors/no-script-component-in-head.md
@@ -1,12 +1,14 @@
-# Script component inside Head component
+# No Script Component in Head
+
+> Prevent usage of `next/script` in `next/head` component.
#### Why This Error Occurred
-The `next/script` component shouldn't be placed inside the `next/head` component
+The `next/script` component should not be used in a `next/head` component.
#### Possible Ways to Fix It
-Move the `` component outside of `...`
+Move the `` component outside of `` instead.
**Before**
diff --git a/errors/no-script-in-document-page.md b/errors/no-script-in-document-page.md
deleted file mode 100644
index 2986bfeebb09c..0000000000000
--- a/errors/no-script-in-document-page.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Script component inside \_document.js
-
-> ⚠️ This error is not relevant in versions 12.1.6 or later. Please refer to the updated [error message](https://nextjs.org/docs/messages/no-before-interactive-script-outside-document).
-
-#### Why This Error Occurred
-
-You can't use the `next/script` component inside the `_document.js` page in versions prior to v12.1.6. That's because the `_document.js` page only runs on the server and `next/script` has client-side functionality to ensure loading order.
-
-#### Possible Ways to Fix It
-
-If you want a global script, instead use the `_app.js` page.
-
-```jsx
-import Script from 'next/script'
-
-function MyApp({ Component, pageProps }) {
- return (
- <>
-
-
- >
- )
-}
-
-export default MyApp
-```
-
-- [custom-app](https://nextjs.org/docs/advanced-features/custom-app)
-- [next-script](https://nextjs.org/docs/basic-features/script#usage)
diff --git a/errors/no-script-in-document.md b/errors/no-script-in-document.md
new file mode 100644
index 0000000000000..6920e464cfe26
--- /dev/null
+++ b/errors/no-script-in-document.md
@@ -0,0 +1,31 @@
+# No Script in Document
+
+> Prevent usage of `next/script` in `pages/_document.js`.
+
+> ⚠️ This error is not relevant in Next.js versions 12.1.6 or later. Please refer to the updated [error message](https://nextjs.org/docs/messages/no-before-interactive-script-outside-document).
+
+#### Why This Error Occurred
+
+You should not use the `next/script` component in `pages/_document.js` in Next.js versions prior to 12.1.6. That's because the `pages/_document.js` page only runs on the server and `next/script` has client-side functionality to ensure loading order.
+
+#### Possible Ways to Fix It
+
+If you want a global script, use `next/script` in `pages/_app.js` instead.
+
+```jsx
+import Script from 'next/script'
+
+function MyApp({ Component, pageProps }) {
+ return (
+ <>
+
+
+ >
+ )
+}
+
+export default MyApp
+```
+
+- [custom-app](https://nextjs.org/docs/advanced-features/custom-app)
+- [next-script](https://nextjs.org/docs/basic-features/script#usage)
diff --git a/errors/no-server-import-in-page.md b/errors/no-server-import-in-page.md
index b7639682d30be..84a1c3e757592 100644
--- a/errors/no-server-import-in-page.md
+++ b/errors/no-server-import-in-page.md
@@ -1,5 +1,7 @@
# No Server Import In Page
+> Prevent usage of `next/server` outside of `middleware.js`.
+
### Why This Error Occurred
`next/server` was imported outside of `middleware.{js,ts}`.
diff --git a/errors/no-styled-jsx-in-document.md b/errors/no-styled-jsx-in-document.md
index 4c9dbf6133386..e7660d73cbb3c 100644
--- a/errors/no-styled-jsx-in-document.md
+++ b/errors/no-styled-jsx-in-document.md
@@ -1,5 +1,7 @@
# No styled-jsx in Document
+> Prevent usage of `styled-jsx` in `pages/_document.js`.
+
### Why This Error Occurred
Custom CSS like `styled-jsx` is not allowed in a [Custom Document](https://nextjs.org/docs/advanced-features/custom-document).
diff --git a/errors/no-sync-scripts.md b/errors/no-sync-scripts.md
index b8a200e8b58d8..36632536b9aed 100644
--- a/errors/no-sync-scripts.md
+++ b/errors/no-sync-scripts.md
@@ -1,14 +1,14 @@
# No Sync Scripts
+> Prevent synchronous scripts.
+
### Why This Error Occurred
-A synchronous script was used which can impact your webpage's performance.
+A synchronous script was used which can impact your webpage performance.
### Possible Ways to Fix It
-#### Script component (experimental)
-
-Use the Script component with the right loading strategy to defer loading of the script until necessary.
+#### Script component (recommended)
```jsx
import Script from 'next/script'
@@ -25,6 +25,13 @@ function Home() {
export default Home
```
+#### Use `async` or `defer`
+
+```html
+
+
+```
+
### Useful Links
- [Efficiently load third-party JavaScript](https://web.dev/efficiently-load-third-party-javascript/)
diff --git a/errors/no-title-in-document-head.md b/errors/no-title-in-document-head.md
index 771e99674d5c4..3f450d18862e6 100644
--- a/errors/no-title-in-document-head.md
+++ b/errors/no-title-in-document-head.md
@@ -1,8 +1,10 @@
# No Title in Document Head
+> Prevent usage of `` with `Head` component from `next/document`.
+
### Why This Error Occurred
-A `` element was defined within the `Head` component imported from `next/document`, which should only be used for any `` code that is common for all pages. Title tags should be defined at the page-level using `next/head`.
+A `` element was defined within the `Head` component imported from `next/document`, which should only be used for any `` code that is common for all pages. Title tags should be defined at the page-level using `next/head` instead.
### Possible Ways to Fix It
diff --git a/errors/no-unwanted-polyfillio.md b/errors/no-unwanted-polyfillio.md
index 6f05aa9a7251a..9d00cbc8579fd 100644
--- a/errors/no-unwanted-polyfillio.md
+++ b/errors/no-unwanted-polyfillio.md
@@ -1,12 +1,14 @@
-# Duplicate Polyfills from Polyfill.io
+# No Unwanted Polyfill.io
+
+> Prevent duplicate polyfills from Polyfill.io.
#### Why This Error Occurred
-You are using Polyfill.io and including duplicate polyfills already shipped with Next.js. This increases page weight unnecessarily which can affect loading performance.
+You are using polyfills from Polyfill.io and including polyfills already shipped with Next.js. This unnecessarily increases page weight which can affect loading performance.
#### Possible Ways to Fix It
-Remove all duplicate polyfills that are included with Polyfill.io. If you need to add polyfills but are not sure if Next.js already includes it, take a look at the list of [supported browsers and features](https://nextjs.org/docs/basic-features/supported-browsers-features) first.
+Remove all duplicate polyfills. If you need to add polyfills but are not sure if Next.js already includes it, take a look at the list of [supported browsers and features](https://nextjs.org/docs/basic-features/supported-browsers-features).
### Useful Links
diff --git a/packages/eslint-plugin-next/lib/index.js b/packages/eslint-plugin-next/lib/index.js
index 9c1b1559b8fc4..0f228b4beb2b6 100644
--- a/packages/eslint-plugin-next/lib/index.js
+++ b/packages/eslint-plugin-next/lib/index.js
@@ -1,60 +1,60 @@
module.exports = {
rules: {
- 'no-css-tags': require('./rules/no-css-tags'),
- 'no-sync-scripts': require('./rules/no-sync-scripts'),
- 'no-html-link-for-pages': require('./rules/no-html-link-for-pages'),
- 'no-img-element': require('./rules/no-img-element'),
- 'no-head-element': require('./rules/no-head-element'),
- 'no-unwanted-polyfillio': require('./rules/no-unwanted-polyfillio'),
- 'no-page-custom-font': require('./rules/no-page-custom-font'),
- 'no-title-in-document-head': require('./rules/no-title-in-document-head'),
'google-font-display': require('./rules/google-font-display'),
'google-font-preconnect': require('./rules/google-font-preconnect'),
+ 'inline-script-id': require('./rules/inline-script-id'),
+ 'next-script-for-ga': require('./rules/next-script-for-ga'),
+ 'no-before-interactive-script-outside-document': require('./rules/no-before-interactive-script-outside-document'),
+ 'no-css-tags': require('./rules/no-css-tags'),
'no-document-import-in-page': require('./rules/no-document-import-in-page'),
+ 'no-duplicate-head': require('./rules/no-duplicate-head'),
+ 'no-head-element': require('./rules/no-head-element'),
'no-head-import-in-document': require('./rules/no-head-import-in-document'),
+ 'no-html-link-for-pages': require('./rules/no-html-link-for-pages'),
+ 'no-img-element': require('./rules/no-img-element'),
+ 'no-page-custom-font': require('./rules/no-page-custom-font'),
'no-script-component-in-head': require('./rules/no-script-component-in-head'),
'no-server-import-in-page': require('./rules/no-server-import-in-page'),
'no-styled-jsx-in-document': require('./rules/no-styled-jsx-in-document'),
+ 'no-sync-scripts': require('./rules/no-sync-scripts'),
+ 'no-title-in-document-head': require('./rules/no-title-in-document-head'),
'no-typos': require('./rules/no-typos'),
- 'no-duplicate-head': require('./rules/no-duplicate-head'),
- 'inline-script-id': require('./rules/inline-script-id'),
- 'next-script-for-ga': require('./rules/next-script-for-ga'),
- 'no-before-interactive-script-outside-document': require('./rules/no-before-interactive-script-outside-document'),
- 'no-assign-module-variable': require('./rules/no-assign-module-variable'),
+ 'no-unwanted-polyfillio': require('./rules/no-unwanted-polyfillio'),
},
configs: {
recommended: {
plugins: ['@next/next'],
rules: {
- '@next/next/no-css-tags': 1,
- '@next/next/no-sync-scripts': 1,
- '@next/next/no-html-link-for-pages': 1,
- '@next/next/no-img-element': 1,
- '@next/next/no-head-element': 1,
- '@next/next/no-unwanted-polyfillio': 1,
- '@next/next/no-page-custom-font': 1,
- '@next/next/no-title-in-document-head': 1,
- '@next/next/google-font-display': 1,
- '@next/next/google-font-preconnect': 1,
- '@next/next/next-script-for-ga': 1,
- '@next/next/no-document-import-in-page': 2,
- '@next/next/no-head-import-in-document': 2,
- '@next/next/no-script-component-in-head': 2,
- '@next/next/no-styled-jsx-in-document': 2,
- '@next/next/no-server-import-in-page': 2,
- '@next/next/no-typos': 1,
- '@next/next/no-duplicate-head': 2,
- '@next/next/inline-script-id': 2,
- '@next/next/no-before-interactive-script-outside-document': 1,
- '@next/next/no-assign-module-variable': 2,
+ // Errors
+ '@next/next/google-font-display': 'error',
+ '@next/next/google-font-preconnect': 'error',
+ '@next/next/next-script-for-ga': 'error',
+ '@next/next/no-before-interactive-script-outside-document': 'error',
+ '@next/next/no-css-tags': 'error',
+ '@next/next/no-head-element': 'error',
+ '@next/next/no-html-link-for-pages': 'error',
+ '@next/next/no-img-element': 'error',
+ '@next/next/no-page-custom-font': 'error',
+ '@next/next/no-styled-jsx-in-document': 'error',
+ '@next/next/no-sync-scripts': 'error',
+ '@next/next/no-title-in-document-head': 'error',
+ '@next/next/no-typos': 'error',
+ '@next/next/no-unwanted-polyfillio': 'error',
+ // Warnings
+ '@next/next/inline-script-id': 'warn',
+ '@next/next/no-document-import-in-page': 'warn',
+ '@next/next/no-duplicate-head': 'warn',
+ '@next/next/no-head-import-in-document': 'warn',
+ '@next/next/no-server-import-in-page': 'warn',
+ '@next/next/no-script-component-in-head': 'warn',
},
},
'core-web-vitals': {
plugins: ['@next/next'],
extends: ['plugin:@next/next/recommended'],
rules: {
- '@next/next/no-sync-scripts': 2,
- '@next/next/no-html-link-for-pages': 2,
+ '@next/next/no-html-link-for-pages': 'warn',
+ '@next/next/no-sync-scripts': 'warn',
},
},
},
diff --git a/packages/eslint-plugin-next/lib/rules/google-font-display.js b/packages/eslint-plugin-next/lib/rules/google-font-display.js
index 7a0995eb7a6fc..a1ca8a9a7a957 100644
--- a/packages/eslint-plugin-next/lib/rules/google-font-display.js
+++ b/packages/eslint-plugin-next/lib/rules/google-font-display.js
@@ -1,12 +1,13 @@
const NodeAttributes = require('../utils/node-attributes.js')
+const url = 'https://nextjs.org/docs/messages/google-font-display'
+
module.exports = {
meta: {
docs: {
- description:
- 'Ensure correct font-display property is assigned for Google Fonts',
+ description: 'Enforce font-display behavior with Google Fonts.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/google-font-display',
+ url,
},
},
create: function (context) {
@@ -33,22 +34,23 @@ module.exports = {
const displayValue = params.get('display')
if (!params.has('display')) {
- message = 'Display parameter is missing.'
+ message =
+ 'A font-display parameter is missing (adding `&display=optional` is recommended).'
} else if (
+ displayValue === 'auto' ||
displayValue === 'block' ||
- displayValue === 'fallback' ||
- displayValue === 'auto'
+ displayValue === 'fallback'
) {
message = `${
displayValue[0].toUpperCase() + displayValue.slice(1)
- } behavior is not recommended.`
+ } is not recommended.`
}
}
if (message) {
context.report({
node,
- message: `${message} See: https://nextjs.org/docs/messages/google-font-display`,
+ message: `${message} See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/google-font-preconnect.js b/packages/eslint-plugin-next/lib/rules/google-font-preconnect.js
index a217618905a5e..cbc1a65ac6821 100644
--- a/packages/eslint-plugin-next/lib/rules/google-font-preconnect.js
+++ b/packages/eslint-plugin-next/lib/rules/google-font-preconnect.js
@@ -1,11 +1,13 @@
const NodeAttributes = require('../utils/node-attributes.js')
+const url = 'https://nextjs.org/docs/messages/google-font-preconnect'
+
module.exports = {
meta: {
docs: {
- description: 'Ensure preconnect is used with Google Fonts',
+ description: 'Ensure `preconnect` is used with Google Fonts.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/google-font-preconnect',
+ url,
},
},
create: function (context) {
@@ -33,7 +35,7 @@ module.exports = {
) {
context.report({
node,
- message: `Preconnect is missing. See: https://nextjs.org/docs/messages/google-font-preconnect`,
+ message: `\`rel="preconnect"\` is missing from Google Font. See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/inline-script-id.js b/packages/eslint-plugin-next/lib/rules/inline-script-id.js
index 2254bd8d47154..d936825912d82 100644
--- a/packages/eslint-plugin-next/lib/rules/inline-script-id.js
+++ b/packages/eslint-plugin-next/lib/rules/inline-script-id.js
@@ -1,10 +1,12 @@
+const url = 'https://nextjs.org/docs/messages/inline-script-id'
+
module.exports = {
meta: {
docs: {
description:
- 'next/script components with inline content must specify an `id` attribute.',
+ 'Enforce `id` attribute on `next/script` components with inline content.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/inline-script-id',
+ url,
},
},
create: function (context) {
@@ -59,8 +61,7 @@ module.exports = {
if (!attributeNames.has('id')) {
context.report({
node,
- message:
- 'next/script components with inline content must specify an `id` attribute. See: https://nextjs.org/docs/messages/inline-script-id',
+ message: `\`next/script\` components with inline content must specify an \`id\` attribute. See: ${url}`,
})
}
}
diff --git a/packages/eslint-plugin-next/lib/rules/next-script-for-ga.js b/packages/eslint-plugin-next/lib/rules/next-script-for-ga.js
index 6d934d3c567cd..260ab65c17d83 100644
--- a/packages/eslint-plugin-next/lib/rules/next-script-for-ga.js
+++ b/packages/eslint-plugin-next/lib/rules/next-script-for-ga.js
@@ -8,8 +8,10 @@ const SUPPORTED_HTML_CONTENT_URLS = [
'www.google-analytics.com/analytics.js',
'www.googletagmanager.com/gtm.js',
]
-const ERROR_MSG =
- 'Use the `next/script` component for loading third party scripts. See: https://nextjs.org/docs/messages/next-script-for-ga'
+const description =
+ 'Prefer `next/script` component when using the inline script for Google Analytics.'
+const url = 'https://nextjs.org/docs/messages/next-script-for-ga'
+const ERROR_MSG = `${description} See: ${url}`
// Check if one of the items in the list is a substring of the passed string
const containsStr = (str, strList) => {
@@ -19,12 +21,12 @@ const containsStr = (str, strList) => {
module.exports = {
meta: {
docs: {
- description:
- 'Prefer next script component when using the inline script for Google Analytics',
+ description,
recommended: true,
- url: 'https://nextjs.org/docs/messages/next-script-for-ga',
+ url,
},
},
+ schema: [],
create: function (context) {
return {
JSXOpeningElement(node) {
@@ -74,5 +76,3 @@ module.exports = {
}
},
}
-
-module.exports.schema = []
diff --git a/packages/eslint-plugin-next/lib/rules/no-before-interactive-script-outside-document.js b/packages/eslint-plugin-next/lib/rules/no-before-interactive-script-outside-document.js
index bc4346749d129..075c61ed73561 100644
--- a/packages/eslint-plugin-next/lib/rules/no-before-interactive-script-outside-document.js
+++ b/packages/eslint-plugin-next/lib/rules/no-before-interactive-script-outside-document.js
@@ -1,12 +1,15 @@
const path = require('path')
+const url =
+ 'https://nextjs.org/docs/messages/no-before-interactive-script-outside-document'
+
module.exports = {
meta: {
docs: {
description:
- 'Disallow using next/script beforeInteractive strategy outside the next/_document component',
+ "Prevent usage of `next/script`'s `beforeInteractive` strategy outside of `pages/_document.js`.",
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-before-interactive-script-outside-document',
+ url,
},
},
create: function (context) {
@@ -46,8 +49,7 @@ module.exports = {
context.report({
node,
- message:
- 'next/script beforeInteractive strategy should only be used inside next/_document. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document',
+ message: `\`next/script\`'s \`beforeInteractive\` strategy should not be used outside of \`pages/_document.js\`. See: ${url}`,
})
},
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-css-tags.js b/packages/eslint-plugin-next/lib/rules/no-css-tags.js
index e361ab137d0d7..765555853019f 100644
--- a/packages/eslint-plugin-next/lib/rules/no-css-tags.js
+++ b/packages/eslint-plugin-next/lib/rules/no-css-tags.js
@@ -1,36 +1,45 @@
-module.exports = function (context) {
- return {
- JSXOpeningElement(node) {
- if (node.name.name !== 'link') {
- return
- }
- if (node.attributes.length === 0) {
- return
- }
+const url = 'https://nextjs.org/docs/messages/no-css-tags'
- const attributes = node.attributes.filter(
- (attr) => attr.type === 'JSXAttribute'
- )
- if (
- attributes.find(
- (attr) =>
- attr.name.name === 'rel' && attr.value.value === 'stylesheet'
- ) &&
- attributes.find(
- (attr) =>
- attr.name.name === 'href' &&
- attr.value.type === 'Literal' &&
- !/^https?/.test(attr.value.value)
- )
- ) {
- context.report({
- node,
- message:
- 'Do not include stylesheets manually. See: https://nextjs.org/docs/messages/no-css-tags',
- })
- }
+module.exports = {
+ meta: {
+ docs: {
+ description: 'Prevent manual stylesheet tags.',
+ recommended: true,
+ url,
},
- }
-}
+ },
+ schema: [],
+ create: function (context) {
+ return {
+ JSXOpeningElement(node) {
+ if (node.name.name !== 'link') {
+ return
+ }
+ if (node.attributes.length === 0) {
+ return
+ }
-module.exports.schema = []
+ const attributes = node.attributes.filter(
+ (attr) => attr.type === 'JSXAttribute'
+ )
+ if (
+ attributes.find(
+ (attr) =>
+ attr.name.name === 'rel' && attr.value.value === 'stylesheet'
+ ) &&
+ attributes.find(
+ (attr) =>
+ attr.name.name === 'href' &&
+ attr.value.type === 'Literal' &&
+ !/^https?/.test(attr.value.value)
+ )
+ ) {
+ context.report({
+ node,
+ message: `Do not include stylesheets manually. See: ${url}`,
+ })
+ }
+ },
+ }
+ },
+}
diff --git a/packages/eslint-plugin-next/lib/rules/no-document-import-in-page.js b/packages/eslint-plugin-next/lib/rules/no-document-import-in-page.js
index 1b7fbeb8f0512..76b46ed9dc1a2 100644
--- a/packages/eslint-plugin-next/lib/rules/no-document-import-in-page.js
+++ b/packages/eslint-plugin-next/lib/rules/no-document-import-in-page.js
@@ -1,12 +1,14 @@
const path = require('path')
+const url = 'https://nextjs.org/docs/messages/no-document-import-in-page'
+
module.exports = {
meta: {
docs: {
description:
- 'Disallow importing next/document outside of pages/document.js',
+ 'Prevent importing `next/document` outside of `pages/_document.js`.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-document-import-in-page',
+ url,
},
},
create: function (context) {
@@ -29,7 +31,7 @@ module.exports = {
context.report({
node,
- message: `next/document should not be imported outside of pages/_document.js. See: https://nextjs.org/docs/messages/no-document-import-in-page`,
+ message: `\`\` from \`next/document\` should not be imported outside of \`pages/_document.js\`. See: ${url}`,
})
},
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-duplicate-head.js b/packages/eslint-plugin-next/lib/rules/no-duplicate-head.js
index cc15c27c83bb8..a8b0521411293 100644
--- a/packages/eslint-plugin-next/lib/rules/no-duplicate-head.js
+++ b/packages/eslint-plugin-next/lib/rules/no-duplicate-head.js
@@ -1,9 +1,12 @@
+const url = 'https://nextjs.org/docs/messages/no-duplicate-head'
+
module.exports = {
meta: {
docs: {
- description: 'Enforce no duplicate usage of in pages/document.js',
+ description:
+ 'Prevent duplicate usage of `` in `pages/_document.js`.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-duplicate-head',
+ url,
},
},
create: function (context) {
@@ -44,8 +47,7 @@ module.exports = {
for (let i = 1; i < headComponents.length; i++) {
context.report({
node: headComponents[i],
- message:
- 'Do not include multiple instances of . See: https://nextjs.org/docs/messages/no-duplicate-head',
+ message: `Do not include multiple instances of \`\`. See: ${url}`,
})
}
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-head-element.js b/packages/eslint-plugin-next/lib/rules/no-head-element.js
index ae8def43c5934..045e21a311316 100644
--- a/packages/eslint-plugin-next/lib/rules/no-head-element.js
+++ b/packages/eslint-plugin-next/lib/rules/no-head-element.js
@@ -1,14 +1,15 @@
+const url = 'https://nextjs.org/docs/messages/no-head-element'
+
module.exports = {
meta: {
docs: {
- description: 'Prohibit usage of HTML element',
+ description: 'Prevent usage of `` element.',
category: 'HTML',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-head-element',
+ url,
},
fixable: 'code',
},
-
create: function (context) {
return {
JSXOpeningElement(node) {
@@ -18,7 +19,7 @@ module.exports = {
context.report({
node,
- message: `Do not use . Use Head from 'next/head' instead. See: https://nextjs.org/docs/messages/no-head-element`,
+ message: `Do not use \`\` element. Use \`\` from \`next/head\` instead. See: ${url}`,
})
},
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-head-import-in-document.js b/packages/eslint-plugin-next/lib/rules/no-head-import-in-document.js
index e65deb425dc16..5a98ebd8497c5 100644
--- a/packages/eslint-plugin-next/lib/rules/no-head-import-in-document.js
+++ b/packages/eslint-plugin-next/lib/rules/no-head-import-in-document.js
@@ -1,11 +1,13 @@
const path = require('path')
+const url = 'https://nextjs.org/docs/messages/no-head-import-in-document'
+
module.exports = {
meta: {
docs: {
- description: 'Disallow importing next/head in pages/document.js',
+ description: 'Prevent usage of `next/head` in `pages/_document.js`.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-head-import-in-document',
+ url,
},
},
create: function (context) {
@@ -28,7 +30,7 @@ module.exports = {
) {
context.report({
node,
- message: `next/head should not be imported in pages${document}. Import Head from next/document instead. See: https://nextjs.org/docs/messages/no-head-import-in-document`,
+ message: `\`next/head\` should not be imported in \`pages${document}\`. Use \`\` from \`next/document\` instead. See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js b/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
index c26f72e851a07..967984492d1fa 100644
--- a/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
+++ b/packages/eslint-plugin-next/lib/rules/no-html-link-for-pages.js
@@ -11,7 +11,7 @@ const {
const pagesDirWarning = execOnce((pagesDirs) => {
console.warn(
`Pages directory cannot be found at ${pagesDirs.join(' or ')}. ` +
- `If using a custom path, please configure with the no-html-link-for-pages rule in your eslint config file`
+ 'If using a custom path, please configure with the `no-html-link-for-pages` rule in your eslint config file.'
)
})
@@ -19,13 +19,16 @@ const pagesDirWarning = execOnce((pagesDirs) => {
// Prevent multiple blocking IO requests that have already been calculated.
const fsExistsSyncCache = {}
+const url = 'https://nextjs.org/docs/messages/no-html-link-for-pages'
+
module.exports = {
meta: {
docs: {
- description: 'Prohibit full page refresh for Next.js pages',
+ description:
+ 'Prevent usage of `` elements to navigate to internal Next.js pages.',
category: 'HTML',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-html-link-for-pages',
+ url,
},
fixable: null, // or "code" or "whitespace"
schema: [
@@ -79,7 +82,7 @@ module.exports = {
return {}
}
- const urls = getUrlFromPagesDirectories('/', foundPagesDirs)
+ const pageUrls = getUrlFromPagesDirectories('/', foundPagesDirs)
return {
JSXOpeningElement(node) {
if (node.name.name !== 'a') {
@@ -121,11 +124,11 @@ module.exports = {
return
}
- urls.forEach((url) => {
- if (url.test(normalizeURL(hrefPath))) {
+ pageUrls.forEach((pageUrl) => {
+ if (pageUrl.test(normalizeURL(hrefPath))) {
context.report({
node,
- message: `Do not use the HTML tag to navigate to ${hrefPath}. Use Link from 'next/link' instead. See: https://nextjs.org/docs/messages/no-html-link-for-pages`,
+ message: `Do not use an \`\` element to navigate to \`${hrefPath}\`. Use \`\` from \`next/link\` instead. See: ${url}`,
})
}
})
diff --git a/packages/eslint-plugin-next/lib/rules/no-img-element.js b/packages/eslint-plugin-next/lib/rules/no-img-element.js
index 8f015e59283a6..a9fcbf2bb1c0e 100644
--- a/packages/eslint-plugin-next/lib/rules/no-img-element.js
+++ b/packages/eslint-plugin-next/lib/rules/no-img-element.js
@@ -1,10 +1,12 @@
+const url = 'https://nextjs.org/docs/messages/no-img-element'
+
module.exports = {
meta: {
docs: {
- description: 'Prohibit usage of HTML element',
+ description: 'Prevent usage of `` element to prevent layout shift.',
category: 'HTML',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-img-element',
+ url,
},
fixable: 'code',
},
@@ -22,7 +24,7 @@ module.exports = {
context.report({
node,
- message: `Do not use . Use Image from 'next/image' instead. See: https://nextjs.org/docs/messages/no-img-element`,
+ message: `Do not use \`\` element. Use \`\` from \`next/image\` instead. See: ${url}`,
})
},
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-page-custom-font.js b/packages/eslint-plugin-next/lib/rules/no-page-custom-font.js
index 7475bedf213bc..61ecf534d8f3f 100644
--- a/packages/eslint-plugin-next/lib/rules/no-page-custom-font.js
+++ b/packages/eslint-plugin-next/lib/rules/no-page-custom-font.js
@@ -1,13 +1,14 @@
const NodeAttributes = require('../utils/node-attributes.js')
const { sep, posix } = require('path')
+const url = 'https://nextjs.org/docs/messages/no-page-custom-font'
+
module.exports = {
meta: {
docs: {
- description:
- 'Recommend adding custom font in a custom document and not in a specific page',
+ description: 'Prevent page-only custom fonts.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-page-custom-font',
+ url,
},
},
create: function (context) {
@@ -137,12 +138,11 @@ module.exports = {
hrefValue.startsWith('https://fonts.googleapis.com/css')
if (isGoogleFont) {
- const end =
- 'This is discouraged. See: https://nextjs.org/docs/messages/no-page-custom-font'
+ const end = `This is discouraged. See: ${url}`
const message = is_Document
- ? `Rendering this not inline within of Document disables font optimization. ${end}`
- : `Custom fonts not added at the document level will only load for a single page. ${end}`
+ ? `Using \`\` outside of \`\` will disable automatic font optimization. ${end}`
+ : `Custom fonts not added in \`pages/_document.js\` will only load for a single page. ${end}`
context.report({
node,
diff --git a/packages/eslint-plugin-next/lib/rules/no-script-component-in-head.js b/packages/eslint-plugin-next/lib/rules/no-script-component-in-head.js
index 90e0fbe4bc8c4..82dc94b7bff3e 100644
--- a/packages/eslint-plugin-next/lib/rules/no-script-component-in-head.js
+++ b/packages/eslint-plugin-next/lib/rules/no-script-component-in-head.js
@@ -1,9 +1,12 @@
+const url =
+ 'https://nextjs.org/docs/messages/no-script-component-in-head-component'
+
module.exports = {
meta: {
docs: {
- description: 'Disallow using next/script inside the next/head component',
+ description: 'Prevent usage of `next/script` in `next/head` component.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-script-component-in-head-component',
+ url,
},
},
create: function (context) {
@@ -42,8 +45,7 @@ module.exports = {
if (scriptTag) {
context.report({
node,
- message:
- "next/script shouldn't be used inside next/head. See: https://nextjs.org/docs/messages/no-script-component-in-head-component",
+ message: `\`next/script\` should not be used in \`next/head\` component. Move \`\` outside of \`\` instead. See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/no-server-import-in-page.js b/packages/eslint-plugin-next/lib/rules/no-server-import-in-page.js
index 154ccbc868ccf..db0110115dd12 100644
--- a/packages/eslint-plugin-next/lib/rules/no-server-import-in-page.js
+++ b/packages/eslint-plugin-next/lib/rules/no-server-import-in-page.js
@@ -1,13 +1,14 @@
const path = require('path')
+const url = 'https://nextjs.org/docs/messages/no-server-import-in-page'
const middlewareRegExp = new RegExp(`^middleware\\.(?:t|j)s$`)
module.exports = {
meta: {
docs: {
- description: 'Disallow importing next/server outside of middleware',
+ description: 'Prevent usage of `next/server` outside of `middleware.js`.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-server-import-in-page',
+ url,
},
},
create: function (context) {
@@ -24,7 +25,7 @@ module.exports = {
context.report({
node,
- message: `next/server should not be imported outside of Middleware. Read more: https://nextjs.org/docs/messages/no-server-import-in-page`,
+ message: `\`next/server\` should not be used outside of \`middleware.js\`. See: ${url}`,
})
},
}
diff --git a/packages/eslint-plugin-next/lib/rules/no-styled-jsx-in-document.js b/packages/eslint-plugin-next/lib/rules/no-styled-jsx-in-document.js
index 5851c80cb1e83..0b0efea0e0e0d 100644
--- a/packages/eslint-plugin-next/lib/rules/no-styled-jsx-in-document.js
+++ b/packages/eslint-plugin-next/lib/rules/no-styled-jsx-in-document.js
@@ -1,11 +1,13 @@
const path = require('path')
+const url = 'https://nextjs.org/docs/messages/no-styled-jsx-in-document'
+
module.exports = {
meta: {
docs: {
- description: 'Disallow using custom styled-jsx inside pages/_document.js',
+ description: 'Prevent usage of `styled-jsx` in `pages/_document.js`.',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-styled-jsx-in-document',
+ url,
},
fixable: 'code',
},
@@ -35,7 +37,7 @@ module.exports = {
) {
context.report({
node,
- message: `styled-jsx can not be used inside pages/_document.js. See https://nextjs.org/docs/messages/no-styled-jsx-in-document.`,
+ message: `\`styled-jsx\` should not be used in \`pages/_document.js\`. See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/no-sync-scripts.js b/packages/eslint-plugin-next/lib/rules/no-sync-scripts.js
index ac3e21302895a..2025750b02564 100644
--- a/packages/eslint-plugin-next/lib/rules/no-sync-scripts.js
+++ b/packages/eslint-plugin-next/lib/rules/no-sync-scripts.js
@@ -1,28 +1,37 @@
-module.exports = function (context) {
- return {
- JSXOpeningElement(node) {
- if (node.name.name !== 'script') {
- return
- }
- if (node.attributes.length === 0) {
- return
- }
- const attributeNames = node.attributes
- .filter((attr) => attr.type === 'JSXAttribute')
- .map((attr) => attr.name.name)
- if (
- attributeNames.includes('src') &&
- !attributeNames.includes('async') &&
- !attributeNames.includes('defer')
- ) {
- context.report({
- node,
- message:
- 'External synchronous scripts are forbidden. See: https://nextjs.org/docs/messages/no-sync-scripts',
- })
- }
+const url = 'https://nextjs.org/docs/messages/no-sync-scripts'
+
+module.exports = {
+ meta: {
+ docs: {
+ description: 'Prevent synchronous scripts.',
+ recommended: true,
+ url,
},
- }
+ },
+ schema: [],
+ create: function (context) {
+ return {
+ JSXOpeningElement(node) {
+ if (node.name.name !== 'script') {
+ return
+ }
+ if (node.attributes.length === 0) {
+ return
+ }
+ const attributeNames = node.attributes
+ .filter((attr) => attr.type === 'JSXAttribute')
+ .map((attr) => attr.name.name)
+ if (
+ attributeNames.includes('src') &&
+ !attributeNames.includes('async') &&
+ !attributeNames.includes('defer')
+ ) {
+ context.report({
+ node,
+ message: `Synchronous scripts should not be used. See: ${url}`,
+ })
+ }
+ },
+ }
+ },
}
-
-module.exports.schema = []
diff --git a/packages/eslint-plugin-next/lib/rules/no-title-in-document-head.js b/packages/eslint-plugin-next/lib/rules/no-title-in-document-head.js
index 9d193362f9543..f2eb7d162b50d 100644
--- a/packages/eslint-plugin-next/lib/rules/no-title-in-document-head.js
+++ b/packages/eslint-plugin-next/lib/rules/no-title-in-document-head.js
@@ -1,8 +1,11 @@
+const url = 'https://nextjs.org/docs/messages/no-title-in-document-head'
+
module.exports = {
meta: {
docs: {
- description: 'Disallow using with Head from next/document',
- url: 'https://nextjs.org/docs/messages/no-title-in-document-head',
+ description:
+ 'Prevent usage of `` with `Head` component from `next/document`.',
+ url,
},
},
create: function (context) {
@@ -39,8 +42,7 @@ module.exports = {
if (titleTag) {
context.report({
node: titleTag,
- message:
- 'Titles should be defined at the page-level using next/head. See: https://nextjs.org/docs/messages/no-title-in-document-head',
+ message: `Do not use \`\` element with \`\` component from \`next/document\`. Titles should defined at the page-level using \`\` from \`next/head\` instead. See: ${url}`,
})
}
},
diff --git a/packages/eslint-plugin-next/lib/rules/no-typos.js b/packages/eslint-plugin-next/lib/rules/no-typos.js
index e517993c57048..22092912fcd58 100644
--- a/packages/eslint-plugin-next/lib/rules/no-typos.js
+++ b/packages/eslint-plugin-next/lib/rules/no-typos.js
@@ -42,7 +42,7 @@ function minDistance(a, b) {
module.exports = {
meta: {
docs: {
- description: 'Prevent common typos',
+ description: 'Prevent common typos in Next.js data fetching functions.',
category: 'Stylistic Issues',
recommended: true,
},
diff --git a/packages/eslint-plugin-next/lib/rules/no-unwanted-polyfillio.js b/packages/eslint-plugin-next/lib/rules/no-unwanted-polyfillio.js
index 891903d18977e..f5751e0e2b6fd 100644
--- a/packages/eslint-plugin-next/lib/rules/no-unwanted-polyfillio.js
+++ b/packages/eslint-plugin-next/lib/rules/no-unwanted-polyfillio.js
@@ -59,19 +59,20 @@ const NEXT_POLYFILLED_FEATURES = [
'es7', // Should be covered by babel-preset-env instead.
]
+const url = 'https://nextjs.org/docs/messages/no-unwanted-polyfillio'
+
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
- description:
- 'Prohibit unwanted features to be listed in Polyfill.io tag.',
+ description: 'Prevent duplicate polyfills from Polyfill.io.',
category: 'HTML',
recommended: true,
- url: 'https://nextjs.org/docs/messages/no-unwanted-polyfillio',
+ url,
},
- fixable: null, // or "code" or "whitespace"
+ fixable: null,
},
create: function (context) {
@@ -118,7 +119,7 @@ module.exports = {
', '
)} ${
unwantedFeatures.length > 1 ? 'are' : 'is'
- } already shipped with Next.js. See: https://nextjs.org/docs/messages/no-unwanted-polyfillio`,
+ } already shipped with Next.js. See: ${url}`,
})
}
}
diff --git a/test/integration/eslint/test/index.test.js b/test/integration/eslint/test/index.test.js
index 31c7be9898851..1ded794432b06 100644
--- a/test/integration/eslint/test/index.test.js
+++ b/test/integration/eslint/test/index.test.js
@@ -59,7 +59,7 @@ describe('ESLint', () => {
const output = stdout + stderr
expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(output).toContain(
'Error: Comments inside children section of tag should be placed inside braces'
@@ -90,9 +90,7 @@ describe('ESLint', () => {
expect(output).toContain(
'Error: Comments inside children section of tag should be placed inside braces'
)
- expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
- )
+ expect(output).toContain('Error: Synchronous scripts should not be used.')
})
test('invalid older eslint version', async () => {
@@ -121,7 +119,7 @@ describe('ESLint', () => {
expect(output).not.toContain('Build error occurred')
expect(output).not.toContain('NoFilesFoundError')
expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(output).toContain('Compiled successfully')
})
@@ -136,7 +134,7 @@ describe('ESLint', () => {
expect(output).not.toContain('Build error occurred')
expect(output).not.toContain('AllFilesIgnoredError')
expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(output).toContain('Compiled successfully')
})
@@ -270,7 +268,7 @@ describe('ESLint', () => {
const output = stdout + stderr
expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(output).toContain(
'Error: Comments inside children section of tag should be placed inside braces'
@@ -285,10 +283,10 @@ describe('ESLint', () => {
const output = stdout + stderr
expect(output).toContain(
- "Warning: Do not use . Use Image from 'next/image' instead."
+ 'Error: Do not use `` element. Use `` from `next/image` instead.'
)
expect(output).toContain(
- 'Error: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
})
@@ -303,11 +301,9 @@ describe('ESLint', () => {
)
const output = stdout + stderr
+ expect(output).toContain('Error: Synchronous scripts should not be used.')
expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
- )
- expect(output).toContain(
- 'Error: next/document should not be imported outside of pages/_document.js.'
+ 'Warning: `` from `next/document` should not be imported outside of `pages/_document.js`.'
)
})
@@ -323,10 +319,10 @@ describe('ESLint', () => {
const output = stdout + stderr
expect(output).toContain(
- "Warning: Do not use . Use Image from 'next/image' instead."
+ 'Error: Do not use `` element. Use `` from `next/image` instead.'
)
expect(output).toContain(
- 'Error: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
})
@@ -393,7 +389,7 @@ describe('ESLint', () => {
'Error: Comments inside children section of tag should be placed inside braces'
)
expect(output).not.toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
})
@@ -407,9 +403,7 @@ describe('ESLint', () => {
expect(output).toContain(
'Error: Comments inside children section of tag should be placed inside braces'
)
- expect(output).toContain(
- 'Warning: External synchronous scripts are forbidden'
- )
+ expect(output).toContain('Error: Synchronous scripts should not be used.')
})
test('max warnings flag errors when warnings exceed threshold', async () => {
@@ -424,10 +418,10 @@ describe('ESLint', () => {
expect(stderr).not.toEqual('')
expect(stderr).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(stdout).not.toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
})
@@ -443,10 +437,10 @@ describe('ESLint', () => {
expect(stderr).toEqual('')
expect(stderr).not.toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
expect(stdout).toContain(
- 'Warning: External synchronous scripts are forbidden'
+ 'Warning: Synchronous scripts should not be used.'
)
})
@@ -462,7 +456,7 @@ describe('ESLint', () => {
const output = stdout + stderr
expect(output).toContain(
- 'warning: External synchronous scripts are forbidden'
+ 'warning: Synchronous scripts should not be used.'
)
expect(stdout).toContain('')
expect(stdout).toContain('2 warnings found')
@@ -576,7 +570,7 @@ describe('ESLint', () => {
)
expect(output).not.toContain('pages/')
- expect(output).not.toContain('External synchronous scripts are forbidden')
+ expect(output).not.toContain('Synchronous scripts should not be used.')
})
test('file flag can selectively lints multiple files', async () => {
@@ -598,11 +592,11 @@ describe('ESLint', () => {
expect(output).toContain('pages/bar.js')
expect(output).toContain(
- "Do not use . Use Image from 'next/image' instead"
+ 'Do not use `` element. Use `` from `next/image` instead.'
)
expect(output).not.toContain('pages/index.js')
- expect(output).not.toContain('External synchronous scripts are forbidden')
+ expect(output).not.toContain('Synchronous scripts should not be used.')
})
})
})
diff --git a/test/unit/eslint-plugin-next/google-font-display.test.ts b/test/unit/eslint-plugin-next/google-font-display.test.ts
index 75d40748c7381..8754fc526c1a5 100644
--- a/test/unit/eslint-plugin-next/google-font-display.test.ts
+++ b/test/unit/eslint-plugin-next/google-font-display.test.ts
@@ -53,7 +53,7 @@ ruleTester.run('google-font-display', rule, {
);
}
}
-
+
export default MyDocument;
`,
],
@@ -76,7 +76,7 @@ ruleTester.run('google-font-display', rule, {
errors: [
{
message:
- 'Display parameter is missing. See: https://nextjs.org/docs/messages/google-font-display',
+ 'A font-display parameter is missing (adding `&display=optional` is recommended). See: https://nextjs.org/docs/messages/google-font-display',
type: 'JSXOpeningElement',
},
],
@@ -98,7 +98,7 @@ ruleTester.run('google-font-display', rule, {
errors: [
{
message:
- 'Block behavior is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
+ 'Block is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
type: 'JSXOpeningElement',
},
],
@@ -120,7 +120,7 @@ ruleTester.run('google-font-display', rule, {
errors: [
{
message:
- 'Auto behavior is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
+ 'Auto is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
type: 'JSXOpeningElement',
},
],
@@ -142,7 +142,7 @@ ruleTester.run('google-font-display', rule, {
errors: [
{
message:
- 'Fallback behavior is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
+ 'Fallback is not recommended. See: https://nextjs.org/docs/messages/google-font-display',
type: 'JSXOpeningElement',
},
],
diff --git a/test/unit/eslint-plugin-next/google-font-preconnect.test.ts b/test/unit/eslint-plugin-next/google-font-preconnect.test.ts
index e5669c91acaa2..d5bbbc717335a 100644
--- a/test/unit/eslint-plugin-next/google-font-preconnect.test.ts
+++ b/test/unit/eslint-plugin-next/google-font-preconnect.test.ts
@@ -42,7 +42,7 @@ ruleTester.run('google-font-preconnect', rule, {
errors: [
{
message:
- 'Preconnect is missing. See: https://nextjs.org/docs/messages/google-font-preconnect',
+ '`rel="preconnect"` is missing from Google Font. See: https://nextjs.org/docs/messages/google-font-preconnect',
type: 'JSXOpeningElement',
},
],
@@ -58,7 +58,7 @@ ruleTester.run('google-font-preconnect', rule, {
errors: [
{
message:
- 'Preconnect is missing. See: https://nextjs.org/docs/messages/google-font-preconnect',
+ '`rel="preconnect"` is missing from Google Font. See: https://nextjs.org/docs/messages/google-font-preconnect',
type: 'JSXOpeningElement',
},
],
diff --git a/test/unit/eslint-plugin-next/inline-script-id.test.ts b/test/unit/eslint-plugin-next/inline-script-id.test.ts
index 2c563481c27a0..569f258ef78f5 100644
--- a/test/unit/eslint-plugin-next/inline-script-id.test.ts
+++ b/test/unit/eslint-plugin-next/inline-script-id.test.ts
@@ -12,7 +12,7 @@ import { RuleTester } from 'eslint'
})
const errorMessage =
- 'next/script components with inline content must specify an `id` attribute. See: https://nextjs.org/docs/messages/inline-script-id'
+ '`next/script` components with inline content must specify an `id` attribute. See: https://nextjs.org/docs/messages/inline-script-id'
const ruleTester = new RuleTester()
ruleTester.run('inline-script-id', rule, {
diff --git a/test/unit/eslint-plugin-next/next-script-for-ga.test.ts b/test/unit/eslint-plugin-next/next-script-for-ga.test.ts
index a40772eeb2e77..cee8ceb4a092e 100644
--- a/test/unit/eslint-plugin-next/next-script-for-ga.test.ts
+++ b/test/unit/eslint-plugin-next/next-script-for-ga.test.ts
@@ -12,7 +12,7 @@ import { RuleTester } from 'eslint'
})
const ERROR_MSG =
- 'Use the `next/script` component for loading third party scripts. See: https://nextjs.org/docs/messages/next-script-for-ga'
+ 'Prefer `next/script` component when using the inline script for Google Analytics. See: https://nextjs.org/docs/messages/next-script-for-ga'
const ruleTester = new RuleTester()
diff --git a/test/unit/eslint-plugin-next/no-before-interactive-script-outside-document.test.ts b/test/unit/eslint-plugin-next/no-before-interactive-script-outside-document.test.ts
index 68bf1209d172c..48789a3e237e3 100644
--- a/test/unit/eslint-plugin-next/no-before-interactive-script-outside-document.test.ts
+++ b/test/unit/eslint-plugin-next/no-before-interactive-script-outside-document.test.ts
@@ -124,7 +124,7 @@ ruleTester.run('no-before-interactive-script-outside-document', rule, {
errors: [
{
message:
- 'next/script beforeInteractive strategy should only be used inside next/_document. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document',
+ "`next/script`'s `beforeInteractive` strategy should not be used outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-before-interactive-script-outside-document",
},
],
},
diff --git a/test/unit/eslint-plugin-next/no-document-import-in-page.test.ts b/test/unit/eslint-plugin-next/no-document-import-in-page.test.ts
index 72ee7a7f3530e..ad98e079309c6 100644
--- a/test/unit/eslint-plugin-next/no-document-import-in-page.test.ts
+++ b/test/unit/eslint-plugin-next/no-document-import-in-page.test.ts
@@ -125,7 +125,7 @@ ruleTester.run('no-document-import-in-page', rule, {
errors: [
{
message:
- 'next/document should not be imported outside of pages/_document.js. See: https://nextjs.org/docs/messages/no-document-import-in-page',
+ '`` from `next/document` should not be imported outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-document-import-in-page',
type: 'ImportDeclaration',
},
],
@@ -139,7 +139,7 @@ ruleTester.run('no-document-import-in-page', rule, {
errors: [
{
message:
- 'next/document should not be imported outside of pages/_document.js. See: https://nextjs.org/docs/messages/no-document-import-in-page',
+ '`` from `next/document` should not be imported outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-document-import-in-page',
type: 'ImportDeclaration',
},
],
@@ -153,7 +153,7 @@ ruleTester.run('no-document-import-in-page', rule, {
errors: [
{
message:
- 'next/document should not be imported outside of pages/_document.js. See: https://nextjs.org/docs/messages/no-document-import-in-page',
+ '`` from `next/document` should not be imported outside of `pages/_document.js`. See: https://nextjs.org/docs/messages/no-document-import-in-page',
type: 'ImportDeclaration',
},
],
diff --git a/test/unit/eslint-plugin-next/no-duplicate-head.test.ts b/test/unit/eslint-plugin-next/no-duplicate-head.test.ts
index 194ea827f83cf..c859e8029136d 100644
--- a/test/unit/eslint-plugin-next/no-duplicate-head.test.ts
+++ b/test/unit/eslint-plugin-next/no-duplicate-head.test.ts
@@ -21,7 +21,7 @@ ruleTester.run('no-duplicate-head', rule, {
static async getInitialProps(ctx) {
//...
}
-
+
render() {
return (
@@ -30,7 +30,7 @@ ruleTester.run('no-duplicate-head', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.js',
@@ -38,7 +38,7 @@ ruleTester.run('no-duplicate-head', rule, {
{
code: `import Document, { Html, Head, Main, NextScript } from 'next/document'
- class MyDocument extends Document {
+ class MyDocument extends Document {
render() {
return (
@@ -53,7 +53,7 @@ ruleTester.run('no-duplicate-head', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.tsx',
@@ -64,7 +64,7 @@ ruleTester.run('no-duplicate-head', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -76,19 +76,19 @@ ruleTester.run('no-duplicate-head', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.js',
errors: [
{
message:
- 'Do not include multiple instances of . See: https://nextjs.org/docs/messages/no-duplicate-head',
+ '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',
+ 'Do not include multiple instances of ``. See: https://nextjs.org/docs/messages/no-duplicate-head',
type: 'JSXElement',
},
],
@@ -97,7 +97,7 @@ ruleTester.run('no-duplicate-head', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -124,14 +124,14 @@ ruleTester.run('no-duplicate-head', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.page.tsx',
errors: [
{
message:
- 'Do not include multiple instances of . See: https://nextjs.org/docs/messages/no-duplicate-head',
+ 'Do not include multiple instances of ``. See: https://nextjs.org/docs/messages/no-duplicate-head',
type: 'JSXElement',
},
],
diff --git a/test/unit/eslint-plugin-next/no-head-element.test.ts b/test/unit/eslint-plugin-next/no-head-element.test.ts
index d1014b9374ef5..25034ab2f57eb 100644
--- a/test/unit/eslint-plugin-next/no-head-element.test.ts
+++ b/test/unit/eslint-plugin-next/no-head-element.test.ts
@@ -67,7 +67,7 @@ ruleTester.run('no-head-element', rule, {
errors: [
{
message:
- "Do not use . Use Head from 'next/head' instead. See: https://nextjs.org/docs/messages/no-head-element",
+ 'Do not use `` element. Use `` from `next/head` instead. See: https://nextjs.org/docs/messages/no-head-element',
type: 'JSXOpeningElement',
},
],
@@ -93,7 +93,7 @@ ruleTester.run('no-head-element', rule, {
errors: [
{
message:
- "Do not use . Use Head from 'next/head' instead. See: https://nextjs.org/docs/messages/no-head-element",
+ 'Do not use `` element. Use `` from `next/head` instead. See: https://nextjs.org/docs/messages/no-head-element',
type: 'JSXOpeningElement',
},
],
diff --git a/test/unit/eslint-plugin-next/no-head-import-in-document.test.ts b/test/unit/eslint-plugin-next/no-head-import-in-document.test.ts
index 8e6edbd7e4ea8..4bcaed90b7a3a 100644
--- a/test/unit/eslint-plugin-next/no-head-import-in-document.test.ts
+++ b/test/unit/eslint-plugin-next/no-head-import-in-document.test.ts
@@ -21,7 +21,7 @@ ruleTester.run('no-head-import-in-document', rule, {
static async getInitialProps(ctx) {
//...
}
-
+
render() {
return (
@@ -31,7 +31,7 @@ ruleTester.run('no-head-import-in-document', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.tsx',
@@ -46,7 +46,7 @@ ruleTester.run('no-head-import-in-document', rule, {
);
- }
+ }
`,
filename: 'pages/index.tsx',
},
@@ -56,7 +56,7 @@ ruleTester.run('no-head-import-in-document', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -70,14 +70,14 @@ ruleTester.run('no-head-import-in-document', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.js',
errors: [
{
message:
- 'next/head should not be imported in pages/_document.js. Import Head from next/document instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
+ '`next/head` should not be imported in `pages/_document.js`. Use `` from `next/document` instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
type: 'ImportDeclaration',
},
],
@@ -86,7 +86,7 @@ ruleTester.run('no-head-import-in-document', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -100,14 +100,14 @@ ruleTester.run('no-head-import-in-document', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document.page.tsx',
errors: [
{
message:
- 'next/head should not be imported in pages/_document.page.tsx. Import Head from next/document instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
+ '`next/head` should not be imported in `pages/_document.page.tsx`. Use `
` from `next/document` instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
type: 'ImportDeclaration',
},
],
@@ -116,7 +116,7 @@ ruleTester.run('no-head-import-in-document', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -130,14 +130,14 @@ ruleTester.run('no-head-import-in-document', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document/index.js',
errors: [
{
message:
- 'next/head should not be imported in pages/_document/index.js. Import Head from next/document instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
+ '`next/head` should not be imported in `pages/_document/index.js`. Use `
` from `next/document` instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
type: 'ImportDeclaration',
},
],
@@ -146,7 +146,7 @@ ruleTester.run('no-head-import-in-document', rule, {
code: `
import Document, { Html, Main, NextScript } from 'next/document'
import Head from 'next/head'
-
+
class MyDocument extends Document {
render() {
return (
@@ -160,14 +160,14 @@ ruleTester.run('no-head-import-in-document', rule, {
)
}
}
-
+
export default MyDocument
`,
filename: 'pages/_document/index.tsx',
errors: [
{
message:
- 'next/head should not be imported in pages/_document/index.tsx. Import Head from next/document instead. See: https://nextjs.org/docs/messages/no-head-import-in-document',
+ '`next/head` should not be imported in `pages/_document/index.tsx`. Use `